Newline in Batchoutput to file - batch-file

i searched & tried for hours to get a newline when using a Batchfile with output -> file.
I am new to batchprograming and need some help. So here is my problem:
What i want :
I have a Batch that ping a spezific Server and writes the result in a "xml" format. This format is not real xml - its a kind of XML that a second app (LCDHost) understand.
Finaly the outfile should contain :
<host>myhost2ping.com</host>
<date>22.12.2013</date>
<time>17:03:25,55</time>
<ping>36</ping>
When getting this LCDHost can read this File and show the result in a external LCD ( im my case a G19 Keyboard).
What i actually get :
<host>myhost2ping.com</host> <date>22.12.2013</date> <time>17:03:25,55</time> <ping> Minimum = 36ms</ping>
My Batch:
:begin
for /f "delims=," %%a in ('ping -n 1 myhost2ping.com') do #echo ^<host^>myhost2ping.com^</host^> ^<date^>%DATE%^</date^> ^<time^>%TIME%^</time^> ^<ping^>%%a^</ping^> > ping.txt
TIMEOUT /T 60
goto :begin
What i already tried :
all versions of & echo.
set ^ as Var
/n, /c/n , /r/n
What i need :
each node ... in his own line
last entry should be cutted to only ms :
From Minimum = 36ms to 36.
thanky you for your help.

Here's another method using your code:
:begin
(for /f "delims=," %%a in ('ping -n 1 myhost2ping.com') do (
echo ^<host^>myhost2ping.com^</host^>
echo ^<date^>%DATE%^</date^>
echo ^<time^>%TIME%^</time^>
echo ^<ping^>%%a^</ping^>
)) > ping.txt
TIMEOUT /T 60
goto :begin

try this:
#echo off
setlocal EnableDelayedExpansion
set NL=^
REM the two empty lines above are required!
:begin
for /f "delims=," %%a in ('ping -n 1 www.google.de^|find "Minimum"') do ( set t=%%a )
rem it's easier to work with the variable outside the for-block:
set "t=%t: =%" :: remove spaces
set "t=%t:Minimum=%" :: remove Minimum
set "t=%t:ms=%" :: remove ms
set "t=%t:~1%" :: remove first char (equal sign)
#echo ^<host^>myhost2ping.com^</host^>!NL!^<date^>%DATE%^</date^>!NL!^<time^>%TIME
%^</time^>!NL!^<ping^>%t%^</ping^> > ping.txt
timeout /t 6
goto :begin

Related

how to check OR condition using if statement in batch script

I have command list which will be executed on several server. There is 2 specific command which gets the logs from system and I need to parse these 2 log files to get only required data, which is currently working from below code. but am not able figure out how to check if command executed is that of those 2 log command if so, proceed with rest of the logic, if not then just skip the next few lines. I am not able to find how can we use if statement in batch script which can have OR condition as well.
although am using for loop currently in which am able to check only one command but not both
command list file content :
ipconfig
sys1/log1
Fdisk
map1/log1
from the above command, I would like to check if either of the command ie, sys1/log1 or map1/log1 then perform below logic
code :
Version:1.0
for /f %%i in ('findstr /li /c:"sys1/log1" /c:"ipconfig" !MyLog!') do (
set "wanted=WARNING MINOR MAJOR"
echo echo severity date time Description > !MyLog!_out.log
(
for /f "tokens=1,2 delims==" %%a in ('type !MyLog!^|findstr "severity= date= time= description="') do (
if "%%a"==" severity" echo\
REM this is four SPACES above before severity
<nul set /p "=%%b "
REM above there is a SPACE and a TAB after %%b
)
echo/
) >>!MyLog!_out.log
type !MyLog!_out.log | findstr /b "severity %wanted%" > !MyLog!_out.log
)
Version:1.1
1 for /f %%i in ('findstr /li /c:"sys1/log1" /c:"ipconfig" !MyLog!') do 2(
3 set "wanted=WARNING MINOR MAJOR"
4 echo echo severity date time Description > !MyLog!_out.log
5 (
6 for /f "tokens=1,2 delims==" %%a in ('type !MyLog!^|findstr "severity= date= time= description="') do (
7 if "%%a"==" severity" echo\
8 REM this is four SPACES above before severity
9 <nul set /p "=%%b "
10 REM above there is a SPACE and a TAB after %%b
11 )
12 echo/
13 ) >>!MyLog!_out.log
14 for %%a in (!MyLog!) do (
15 echo %%a | find /n /i !wanted! >> !MyLog!_out.log
16 echo %%a
17 )
18 )
Any idea/suggestion/help please.
MyLog.log output :
echo severity date time Description
MINOR 01/04/2015 08:56 Maintenance note: App logs cleared through sys tool
WARNING 02/22/2015 19:59 POST Error: Caching will be enabled once Super-Cap has been charged. No action is required.
WARNING 03/13/2015 14:34 POST Error: Caching will be enabled once Super-Cap has been charged. No action is required.
MAJOR 10/13/2015 15:03 Network Adapter Link Down (Slot 0, Port 1)
MAJOR 01/13/2016 13:03 Network Adapter Link Down (Slot 0, Port 0)
MAJOR 01/21/2016 02:39 Network Adapter Link Down (Slot 0, Port 0)
MAJOR 06/09/2016 01:01 Network Adapter Link Down (Slot 0, Port 0)
Once you implemented rojo's suggestion, incorporate this script instead of yours inner loop inside the outer FOR loop, and post here if any issues:
#echo off
setlocal enabledelayedexpansion
-------------------------------------
rem Inside your outer FOR loop, add this construct
set "wanted=WARNING MINOR MAJOR"
for %%a in ("%wanted%") do (
for %%b in (!MyLog!) do (
echo %%b | find /n /i %%a >nul >> !MyLog!_out.log
echo %%a %%b))

Second instance of batch loop does not run

I am trying to create a DOS batch script on my Windows 7 machine. I want to execute file 123456.bat, which contains the following command and parameters:
call **startSelenium.bat** 55 someSuiteName suite-someSuite.html development 1 1 10 10
That script calls into the startSelenium.bat script below:
Setlocal EnableDelayedExpansion
SET TimeStamp=
FOR /f "tokens=1-4 delims=/ " %%i in ("%date%") do set datestr=%%l%%j%%k
FOR /f "tokens=1-4 delims=.: " %%i in ("%time%") do set timestr=%%i%%j%%k%%l
SET TimeStamp=%datestr%%timestr%
set a=2
set b=0
set /a c=%a%+%b%
FOR /l %%t IN (1, 1, %c%) do (
call :SEARCHPORT %%t
echo %startPort%
Start java -jar C:\Selenium\2\selenium-server-standalone-2.47.1.jar -port %startPort% -singleWindow -userExtensions C:\selenium\2\user-extensions.js -firefoxProfileTemplate "c:\selenium\2\ffprofiles\2rc" -htmlSuite "*chrome" "https://www.google.com" "Z:\selenium\2\environment\%4\suites\%3" "u:\results\%4\result-%1-%computername%-1234-%TimeStamp%.htm"
timeout /t 10
)
GOTO :EOF
:SEARCHPORT
netstat -o -n -a | find "LISTENING" | find ":%startPort% " > NUL
if "%ERRORLEVEL%" equ "0" (
set /a startPort +=1
GOTO :SEARCHPORT
) ELSE (
set freePort=%startPort%
echo %startPort%
GOTO :EOF
When I run the script, the first instance of the java applications runs with a free Windows port that the SEARCHPORT subroutine found; however, the second instance pops up and quits immediately. I suspect the code is using the same variable from the first time it went through the FOR loop instead of getting a new unused port number.
What am I doing wrong? I copied various parts of this code from other sources. I am obviously a nube, so plain English would be helpful. :)
You have got an delayed expansion issue.
You already enabled delayed expansion, but you don't use it. You have to replace %startPort% with !startPort! inside your for /l loop.

batch file to read a specific string from txt

I need some help to adjust a simple text.
I have generated a file from the command getmac.
The file looks like this:
1
2 F0-79-59-62-20-EB \Device\Tcpip_{F4744941-2A87-4DFA-A61B-393B8830B0C3}
3
My goal is to get to this point:
1 F0-79-59-62-20-EB
2
3
I.e. delete every string after the MAC and move it to the first line
or just read the mac and insert it to a variable without editing it at all
Thanks
Best regards,
Mike
C:\Users\Test\Desktop>SETLOCAL EnableDelayedExpansion
C:\Users\Test\Desktop>FOR /F "tokens=*" %a IN (c:\mymac.txt) DO (
SET line=%a
IF "!line:~0,2!" == "2 " SET macline=%a
)
C:\Users\Test\Desktop>(
SET line=F0-79-59-62-20-EB \Device\Tcpip_{F4744941-2A87-4DFA-A61B-
}
IF "!line:~0,2!" == "2 " SET macline=F0-79-59-62-20-EB \Device\Tcpip_{F474494
1-2A87-4DFA-A61B-393B8830B0C3}
)
C:\Users\Test\Desktop>FOR /F "tokens=2 delims= " %m IN ("") DO (
SET mac=%m
ECHO
)
C:\Users\Test\Desktop>pause
Press any key to continue . . .
The format of your generated file seems to be totally different from the output of the getmac command - at least, it is on my machine.
You should be able to use (from the prompt - but most responses on SO are of a batch file)
FOR /F %a IN ('getmac') DO SET mac=%a
echo %mac%
If I've understood the question right, this should work:
#ECHO OFF
SETLOCAL EnableDelayedExpansion
FOR /F "tokens=*" %%a IN (input.txt) DO (
SET line=%%a
IF "!line:~0,2!"=="2 " SET macline=%%a
)
FOR /F "tokens=2 delims= " %%m IN ("!macline!") DO (
SET mac=%%m
)
At this point the mac ist stored in the %mac% variable. If you want to output it into your file, append this to the code:
ECHO 1 %mac% > output.txt
ECHO. >> output.txt
ECHO 2 >> output.txt
ECHO 3 >> output.txt
If you want to reuse the mac, it's stored in %mac%.

Concerning batch games, find and replace a string

I have made a character file in which my game pulls data and variables from. Looks like so:
playerName= Marche
playerRace= Elf
playerHP= 100
playerSPD= 200
playerATK= 120
playerDEF= 70
Final Fantasy reference anyone...? Anyway, when the character levels up, I need a batch script to find the string "playerHP= 100". playerHP is set as a variable within the script. Basically, it takes the current health, and multiplies it by 120%, increasing the number. How do I echo the result of that math to replace the current number?
For example if that didn't make any sense, I have 100 health. I level up, thus increasing my health stat by 120%, so now I have 120 health. I would want to find the string "playerHP= 100" and replace it with "playerHP= 120".
If it can be avoided I don't want to download any other commands (I've seen sed a few times). Thanks much
EDIT: Instead of searching for the string and replacing I took jeb's advice and just deleted the file and re-echoed all of the data. It ended up looking like this:
set /a LeveledUpPlayerHP=(%ppHP%* 12) / (10)
set /a LeveledUpPlayerSPD=(%ppSPD%* 12) / (10)
set /a LeveledUpPlayerATK=(%ppATK%* 12) / (10)
set /a LeveledUpPlayerDEF=(%ppDEF%* 12) / (10)
echo Updating stats...
del "C:\Users\%USERNAME%\Desktop\CMDRPG\player\playerData.dll
ping 1.1.1.1 -n 1 -w 500 > nul
echo playerName= %playerName%>playerData.dll
echo playerRace= %playerRace%>>playerData.dll
echo playerHP= %LeveledUpPlayerHP%>>playerData.dll
echo playerSPD= %LeveledUpPlayerSPD%>>playerData.dll
echo playerATK= %LeveledUpPlayerATK%>>playerData.dll
echo playerDEF= %LeveledUpPlayerDEF%>>playerData.dll
The playerName and playerRace are all loaded in prior to this section of the code. Ping is used just as a wait function to let the file delete before echoing new data. Seems to work okay. Thanks all
try this (output is in %inifile%.new):
#ECHO OFF &SETLOCAL ENABLEDELAYEDEXPANSION
SET "inifile=file"
FOR /f %%a IN ('^<"%inifile%" find /c /v ""') DO SET /a lines=%%a
< "%inifile%" (
FOR /l %%a IN (1,1,%lines%) DO (
SET "line="
SET /p "line="
IF NOT "!line:playerHP=!"=="!line!" (
FOR /f "tokens=2delims= " %%b IN ("!line!") DO SET /a HP=%%b*12/10
SET "line=playerHP= !HP!"
)
ECHO(!line!
))>"%inifile%.new"
Input/output:
>type file
playerName= Marche
playerRace= Elf
playerHP= 100
playerSPD= 200
playerATK= 120
playerDEF= 70
>test.bat
>type file.new
playerName= Marche
playerRace= Elf
playerHP= 120
playerSPD= 200
playerATK= 120
playerDEF= 70
Presumeably it does not matter what order the values appear in you file. If that is so, then the following will effectively "edit" your file.
It first uses FINDSTR to isolate the current playerHP value, and FOR /F to parse out the value from the string. SET /A increments the playerHP. Then a new file is created using FINDSTR to write all the current values except for playerHP, and then the new playerHP info is appended to the end.
#echo off
set "file=gameData.txt"
for /f "tokens=2 delims==" %%N in ('findstr /bl "playerHP=" "%file%"') do set /a "newHP=%%N*120/100"
>"%file%.mod" (
findstr /blv "playerHP=" "%file%"
echo playerHP=%newHP%
)
move /y "%file%.mod" "%file%" >nul
But why go to all that trouble. I should think you already have all your values in memory as environment variables. Simply make sure that all variables that are to be stored in a file start with a common unique prefix. In your example, they all start with "player", but you probably want something a little more generic - perhaps a symbol like #. So you could have #playerName, #playerRace, etc.
Simply update the values in memory as needed. When it comes time to save the current game state to a file, then all you need to do is
>"gameData.txt" set #
A brand new file will be created each time containing all the current values.
To load the values, you do exactly what jeb suggested:
for /f "usebackq delims=" %%A in ("gameData.txt") do set %%A
To save your data in a file, you could use a block like
(
echo playerName=%playerName%
echo playerRace=%playerRace%
echo playerHP=%playerHP%
) > player.ini
And to load it you could use
for /F "delims=" %%L in (player.ini) do set "%%L"

Batch File w/ Delayed Variable Expansion - URL Encoding - equal sign - RSA Token Converter

I am automating RSA soft token conversion and passing the conversion string over to Outlook. I realize I cannot make the string into a URL using a batch to outlook command line, however that is not my issue. My issue is converting the pesky equal sign over to it's URL encoded equivalent, "%3D".
#echo off
setlocal enableDelayedExpansion
set /p fname=Enter the Filename:
set /p pss=Enter the encryption pass:
IF NOT EXIST "%fname%".sdtid (
echo File Not Found! Closing...
PING 1.1.1.1 -n 4 >NUL
exit
)
echo File Found! starting process...
REM tokenconverter %fname%.sdtid -iphone >> temp_batch.txt
tokenconverter %fname%.sdtid -p %pss% -iphone >> temp_batch.txt
set /p result= < temp_batch.txt
DEL temp_batch.txt
REM %result% | clip
set "stringclean1=!result:?=%%3F!"
set "stringclean2=!stringclean1::=%%3A!"
set "stringclean3=!stringclean2:/=%%2F!"
The following line fails to encode the equal sign:
set "stringclean4=!stringclean3:==%%3D!"
I've tried:
set "stringclean4=!stringclean3:=^=%%3D!"
set "stringclean4=!stringclean3:=%=%%3D!"
However the equal sign remains unencoded.
echo Piping over to outlook..
REM passing stringclean3 since stringclean4 no worky.
pushd "C:\Program Files\Microsoft Office\Office12"
outlook.exe /c ipm.note /m "&subject=TEsT&body=%stringclean3%"
What is the proper way to URL encode the equal sign using delayed variable expansion?
Any assistance is appreciated. Thanks in advance.
Sorry, a simple solution for replacing = in batch simply does not exist :-(
About the best you can do using pure batch is to loop through the string, character by character, and replace as needed.
Here is a brute force solution that has some room for more optimization. But it is good enough. It first checks to see if = exists before taking the time to encode =.
:: test if string contains =
:: only take the time to encode = if it exists
set "test=a!stringClean3!"
for /f "delims=" %%S in ("!test!") do if /i "!test:%%S=%%S!" neq "!test!" (
:: compute length of string - 1
set end=0
for /l %%A in (12,-1,0) do (
set /a "end|=1<<%%A"
for %%B in (!end!) do if "!stringClean3:~%%B,1!"=="" set /a "end&=~1<<%%A"
)
:: replace = with %3D
for /l %%N in (0 1 !end!) do (
if "!stringClean3:~%%N,1!" equ "=" (
set "stringClean4=!stringClean4!%%3D"
) else (
set "stringClean4=!stringClean4!!stringClean3:~%%N,1!"
)
)
) else set stringClean4=!stringClean3!
EDIT
Here is another completely different approach that uses CERTUTIL to encode and decode the string as hex. It is a simple matter to encode the hex string. I don't think CERTUTIL is delivered with XP. I can't remember, but the CERTUTIL syntax may change slightly depending on the version of Windows. I developed and tested this on Vista.
set "tempFile=%temp%\replaceEqual%random%"
(>"%tempFile%.before" echo(!stringClean3!)
certutil -encodehex "%tempFile%.before" "%tempFile%.hex" >nul
>"%tempFile%.hex2" (
for /f "usebackq tokens=1*" %%A in ("%tempFile%.hex") do (
set ln=%%B
set "ln=!ln:~0,48!"
(echo !ln:3d=25 33 44!)
)
)
certutil -decodehex "%tempFile%.hex2" "%tempFile%.after" >nul
<"%tempFile%.after" set /p "stringClean4="
del "%tempFile%.*"
The use of SET /P to read the result leads to the following limitations:
the string must be less than or equal to 1021 characters long.
the string must not end with a control character (trailing control chars are stripped)
the string must not contain line feeds
The result could be read using FOR /F, but then the delayed expansion will corrupt any ! when the FOR variable is expanded.
dbenham had a good idea about using JScript's encodeURIComponent method. Here it is, stuffed into the OP's example script:
#echo off
setlocal
set /p fname=Enter the Filename:
set /p pss=Enter the encryption pass:
IF NOT EXIST "%fname%".sdtid (
echo File Not Found! Closing...
PING 1.1.1.1 -n 4 >NUL
exit
)
echo File Found! starting process...
echo WScript.Stdout.WriteLine(encodeURIComponent(WScript.StdIn.ReadLine()));>uri.js
for /f "delims=" %%I in (
'tokenconverter %fname%.sdtid -p %pss% -iphone ^| cscript /nologo uri.js'
) do set "result=%%I"
del uri.js
SET result=qm?colon:slash/equal=qm?colon:slash/equal=end
set "stringclean0=!result!"
:loop3D
FOR /f "tokens=1,2*delims==" %%i IN ('SET stringclean0') DO (
IF NOT "%%k"=="" set stringclean0=%%j%%3D%%k&GOTO loop3D
)
set "stringclean1=!stringclean0:?=%%3F!"
set "stringclean2=!stringclean1::=%%3A!"
set "stringclean3=!stringclean2:/=%%2F!"
SET stri

Resources