I am trying to get the total time to access a page and using this command:
curl -o NUL -s -w "%%{time_total}" http://stackoverflow.com
I am able to get the total time displayed in the command prompt.
However, now I would like to put this in a for loop like this:
echo off
SET /a i=0
:loop
IF %i%==10 GOTO END
echo Iteration %i%.
SET /a i=%i%+1
GOTO LOOP
:end
and sum up all the times I get, replacing echo Iteration %i%. with something like
set /a var = curl -o NUL -s -w "%%{time_total}" http://stackoverflow.com
set /a vartotal = var + vartotal
But of course this doesn't work, and I know its partially because the times returned are decimal and batch can't handle decimals. Also, the URL may have non-alphabetic charcters in it such as ?, =, and &. Please help
The easiest way to do this is by redirecting the output of the result of the curl command to a file and the process that file.
It is a little bit more tricky because the number contains a comma (maybe a dot in your environment) and the command interpreter only does integer calculation and on my box it interpreted the number wrong. In addition if it the number started with a zero it assumed it was an OCTAL number so you have to strip that as well. Adding all this together would give you this command batch script:
set site=http://stackoverflow.com
set file=so.log
rem set this to , or . depending on your locale
set sep=,
set tot=0
del /Q %file%
rem add 10 values to the so.log file
for /L %%r in (1,1,10) do curl -o NUL -s -w "%%{time_total}\r\n" %site% >> %file%
rem read each line from the file
for /F %%a in (%file%) do call :sum "%%a"
goto :end
rem sum procedure takes a number as first parameter
:sum
set milli=%1
IF "%sep%"=="," set val=%milli:,=%
IF "%sep%"=="." set val=%milli:.=%
set val2=%val:"=%
rem strip 0 if that is the first char
rem otherwise the number is
rem considered to be octal
set lz=%val2:~0,1%
if #%lz%==#0 set val2=%val2:~1%
set /a "tot=tot+%val2%"
set milli=
set val=
set val2=
goto :EOF
:end
echo total time: %tot%
rem clean up
set sep=
set tot=
set site=
set file=
Related
I am writing a batch script and I am having trouble echoing a variable, here is the script,
#echo off
set num1=1
set num2=10
set /a "out=%num1%*%num2%"
echo %out%
pause`
The output I receive is 10 which makes sense but I want it to echo 'num1' ten times instead of multiplying 'num1' by 'num2'. So I want the output to be 1111111111.
Also I don't want to loop the command 10 times as I am putting the output into a text file with 'output>> file.txt' otherwise I will end up with this in the text file,
1
1
1
1
1
1
1
1
1
1
I want to end up with 1111111111, thank you.
#ECHO OFF
SETLOCAL
set num1=1
set num2=10
SET "out="&FOR /L %%a IN (1,1,%num2%) DO CALL SET "out=%%out%%%%num1%%"
echo %out%
GOTO :EOF
The SET "out=" and FOR /L %%a IN (1,1,%num2%) DO CALL SET "out=%%out%%%%num1%%" may be on separate lines if desired. Setting out to nothing is simply a safety measure to ensure that if it contains a value, it's cleared first.
The for /L performs the call command num2 times.
The call command executes SET "out=%out%%num1%" in a subprocess because each %% is interpreted as an escaped-% (% is the escape character for %) - "escaping" a character means turning off its special meaning.
The syntax SET "var=value" (where value may be empty) is used to ensure that any stray trailing spaces are NOT included in the value assigned.
Just to show a different method with set /A and a loop:
#echo off
set /A "num1=1,num2=10,out=0"
:loop
set /a "out*=10,out+=num1,num2-=1"
If %num2% gtr 0 goto :loop
echo %out%
pause
This is the simplest way to solve this problem, using Delayed Expansion.
#echo off
setlocal EnableDelayedExpansion
set num1=1
set num2=10
set "out="
for /L %%i in (1,1,%num2%) do set "out=!out!%num1%"
echo %out%
pause
PS - The multiply term is not exact in this case; perhaps "echo a variable the times indicated by another variable" be more clear...
If what you want is to print num1 num2 times in the same line you can do something like:
#echo off
set "num1=1"
set "num2=10"
(for /L %%i in (1,1,%num2%) do set /p "=%num1%" <nul
echo()>file.txt
The command set /p "=%num1%" <nul prints the text %num1% in the current line without the LF character. So num1 gets printed num2 times in the same line.
I have multiple TraceRT log files containing 30 hops. I'm only looking for similar IP (ex. 192.168.1) and would like to log it on one file with:
1) Successful: %IP% found in %Filename%
2) Fail: Specified IP not found in %Filename%
I'm trying to use:
rem************************************************************
:START
# ECHO OFF
rem US date
set YEAR=%DATE:~10,4%
set MONTH=%DATE:~4,2%
set DAY=%DATE:~7,2%
rem US hour
set HOUR=%TIME:~0,2%
set MIN=%TIME:~3,2%
set SEC=%TIME:~6,2%
set HUNDREDS=%TIME:~9,2%
set HOURMIN=%HOUR%%MIN%
rem Make sure that hour has two digits
IF %HOUR% GEQ 10 goto twoh
set HOUR1=%TIME:~1,1%
set TWOHOUR=0%HOUR1%
goto fulltid
:twoh
set TWOHOUR=%HOUR%
:fulltid
set FULLTIME=%TWOHOUR%'%MIN%'%SEC%'%HUNDREDS%
set FTIME=%TWOHOUR%:%MIN%:%SEC%
#echo off & setLocal EnableDELAYedeXpansion
findstr /m "192.168.1" *.txt > FILENAME
echo on
for /f "tokens=*" %%a in (*.txt ^| find "192.168.1") do (
IF %%a neq %%b (
echo Suscessful: %%a %FILENAME% >> Log%YEAR%%MONTH%%DAY%.txt
) ELSE (
echo Fail: Specified IP not found in %FILENAME% >> Log%YEAR%%MONTH%%DAY%.txt
)
)
goto START
rem************************************************************
You have specified an invalid pipe | find. You cannot pipe (a) text file(s) into a command.
Either provide the file(s) as argument(s) to find, or use redirection (this works for a single file only but not for multiple ones nor */? patterns though).
You are using for /f not correctly.
It looks as if you wanted to parse the output of find. To accomplish that, but you must enclose the command within single-quotes '. Type for /? and see the help text for more details.
The following line of code should work:
for /f "tokens=*" %%a in ('find "192.168.1" *.txt') do (
To get current date and time, I strongly recommend to read variables %DATE% and %TIME% once only and within a single line! Otherwise you might run into problems, especially concerning the fractional seconds, which might not be equal between consecutive expansions.
To ensure %HOUR% to have two digits, you simply need to use set HOUR=0%HOUR% then set HOUR=%HOUR:~-2%.
Since a one-digit %HOUR% is prefixed by a space here, you can have it even simpler (thanks for your comment, #Stephan!) by just replacing the space by a zero: set HOUR=%HOUR: =0%.
I would like split a string in two part with = as delimiter.
I saw this post but I do not manage ta adapt.
I try this:
set "str=4567=abcde"
echo %str%
set "var1=%str:^=="^&REM #%
echo var1=%var1%
Why it does not work?
While not a bulletproof solution (use the for, artoon), without more info, this can do the work
#echo off
setlocal enableextensions enabledelayedexpansion
set "str=4567=abcde"
rem Step 1 - remove the left part
set "str1=!str:%str%!"
rem Step 2 - Get the right part
set "right=!str:*%str1%!"
rem Step 3 - Get the left part
set "left=!str:%right%=!"
set "left=%left:~0,-1%"
echo [%left%] [%right%]
edited to adapt to comments (OP code in comments adapted to my code, or the reverse)
for /f "delims=" %%i in ('set') do (
setlocal enabledelayedexpansion
rem Step 1 - remove the left part
set "str=%%i"
for %%x in ("!str!") do set "str1=!str:%%~x!"
rem Step 2 - Get the right part
for %%x in ("!str1!") do set "right=!str:*%%~x!"
rem Step 3 - Get the left part
for %%x in ("!right!") do set "left=!str:%%~x=!"
set "left=!left:~0,-1!"
echo [!left!] [!right!]
endlocal
)
And no, as previously indicated this is not bulletproof and some of the variables show problems (had I said it is not bulletproof?).
What i don't understand is the requirement to not use a for loop and then use a for loop. It is a lot easier this way
for /f "tokens=1,* delims==" %%a in ('set') do (
echo [%%a] [%%b]
)
Another alternative (not as easy as the for, more stable than the previous one, non bulletproof) is
for /f %%a in ('set') do (
call :split left right %%a
echo [!left!] [!right!]
)
goto :eof
:split leftVar rightVar data
set "%~1=%~3"
setlocal enabledelayedexpansion
set "data=%*"
set "data=!data:*%1 %2 %3=!"
set "data=%data:~1%"
endlocal & set "%~2=%data%"
goto :eof
As npocmaka commented above, = has special meaning and cannot be replaced with traditional variable string manipulation. If you know the length of either side of the equal sign, you could strip off a number of characters. For example, if "4567" will always be 4 characters, you could set "var1=%str:~0,4%". Or if "abcde" will always be 5 characters, you could set "var1=%str:~0,-6%" (5 chars + 1 for the equal sign).
Otherwise, a for loop is your only other option without using 3rd party utilities.
for /f "delims==" %%I in ("%str%") do set "var1=%%I"
If you've got grep installed, you can do something like:
echo %str% | grep -P -o "^[^=]*"
... but you'd still need to capture its output with another for /f loop.
If you are allergic to for loops, and as an exercise in providing a solution to your question without any regard for efficiency, here's how you get the first half of your string without using a single for loop. Put grep and its dependencies in your %PATH%. Then:
echo %str% | grep -P -o "^[^=]*" >temp.txt
set /P "var1="<temp.txt
del temp.txt
echo %var1%
There, I fixed it!
I am trying to write a batch script which does the following actions:
Read arguments inserted into the 'startCounter' & 'endCounter' variable
Having a step value of 1
Write to concurrent CSV files to multiple directories. All CSV file contains the same data, only writing to different directories.
I have tested the following code successfully. For some reasons when I change value '1006000' to some other values like '00000001' and etc, the script does not work.
#ECHO OFF
for /l %%x in (1006000,1,1007000) do (
echo %%x
echo %%x>>C:\apache-jmeter-2.11\script\testdata1\ORDER_ID5.csv
echo %%x>>C:\apache-jmeter-2.11\script\ASAP\testdata2\ORDER_ID5.csv
echo %%x>>C:\apache-jmeter-2.11\script\ASAP\testdata3\ORDER_ID5.csv
echo %%x>>C:\apache-jmeter-2.11\script\ASAP\testdata4\ORDER_ID5.csv
echo %%x>>C:\apache-jmeter-2.11\script\ASAP\testdata5\ORDER_ID5.csv
echo %%x>>C:\apache-jmeter-2.11\script\ASAP\testdata6\ORDER_ID5.csv
echo %%x>>C:\apache-jmeter-2.11\script\ASAP\testdata7\ORDER_ID5.csv
echo %%x>>C:\apache-jmeter-2.11\script\ASAP\testdata8\ORDER_ID5.csv
)
Hence, I am trying to make a more flexible script which generates CSV file, and the CSV filename displays total records generated by the batch script.
#ECHO OFF
set startCounter = 1000000
set endCounter = 1050000
set totalRecords = %endCounter%-%startCounter%
set name = NewDataGen_%startCounter%_to_%endCounter%_%totalRecords%.csv
for /l %%x in (%startCounter%,1,%endCounter%) do (
echo %%x
echo %%x>>%name%
)
Thanks for your help!
Your problems are simple to solve and consistent in nature.
set startCounter = 1000000
set endCounter = 1050000
as examples.
The set "var=value" syntax ensures that any trailing spaces on the batch line are not included in the value assigned to var.
Batch is sensitive to spaces in a SET statement. SET FLAG = N sets a variable named "FLAGSpace" to a value of "SpaceN"
But the set/a syntax acts less particularly and MUST be used for calculations. It only works for integer values.
set startCounter=1000000
will work happily, if there are no trailing spaces on the line
set /a startCounter=1000000
will work happily, regardless of trailing spaces
set /a startCounter = 1000000
will also work happily, regardless of trailing spaces
set /a totalRecords = %endCounter%-%startCounter%
set /a totalRecords=%endCounter%-%startCounter%
set /a totalRecords = endCounter-startCounter
set /a totalRecords=endCounter-startCounter
(and other constructs) Will all calculate totalrecords (case is largely irrelevant in batch.) The /a means 'process in arithmetic mode'.
(Personal preference for the second format. YMMV)
Ok got it already. The script is as below. Thanks a lot Magoo!
#ECHO OFF
set /a startCounter=1000000
set /a endCounter=1000100
set /a totalRecords=%endCounter%-%startCounter%
set name=NewDataGen_%startCounter%_%endCounter%_%totalRecords%.csv
for /l %%x in (%startCounter%,1,%endCounter%) do (
echo %%x
echo %%x>>%name%
)
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