Increment a variable on each cycle in a batch file? - loops

I have a batch script which loops and I want to count how many cycles it has done.
This is how the script looks:
#echo off
title MyTitle
set cycles=0
:startpoint
echo %cycles%
(my command)
goto startpoint
I would like to be able to see the variable "cycles" increment by 1 each time it goes back to :startpoint, how do i do that?

To perform arithmetic operations in batch you need to use the /a switch with the set command:
#echo off
title MyTitle
set cycles=0
:startpoint
set /a cycles=cycles+1
echo %cycles%
...
(my command)
...
goto startpoint
Type set /? in cmd for more information.

Using this code
setlocal enableextensions enabledelayedexpansion
set /a count = 1
for /f "tokens=*" %%a in (config.properties) do (
set /a count += 1
echo !count!
)
endlocal
works for me, the reason because I was using %count% instead of !count! so I keep getting 1 instead of the expected output. So if using %% doesn't work for you, you can as well use !! to either display your output or do your calculations or comparisons.

well this worked for me.
#echo off
setlocal enabledelayedexpansion
SET /A i = 1
for /f "tokens=*" %%f in (temp.txt) do (
IF !i!==2 echo %%f
SET /a i+=1
)

Related

Formatting generated numbers in a .bat file

Forgive me if there is a simple answer to this, I'm new to all of this.
The below .bat script generates a list of numbers depending on how many numbers you want.
However what I would like is to format the numbers it generate.
For example, if I input 20, instead of it coming out 1, 2, 3 etc. I would like it to come out as 001, 002... 020.
Is this possible? Am I missing something obvious?
Many Thanks.
#echo off
setlocal EnableExtensions
:start
cls
set /p loopcount= How Many Users?:
set "x="0"
:loop
set /a "x+=1"
echo %x%
set /a loopcount=loopcount-1
if %loopcount%==0 goto exitloop
goto loop
:exitloop
pause
goto start
just implementing SomethingDark's suggestion (and a minor change in the logic of the loop):
set /p "loopcount= How Many Users?: "
set "x=1000"
:loop
set /a x+=1
echo %x:~-3%
set /a loopcount-=1
if %loopcount% gtr 0 goto :loop
echo loop finished.
(btw: your set "x="0" has a quote too much (probably a typo)
Here's a quick example batch file which uses powershell for your leading zeroes.
I have used a for loop as the looping mechanism.
#Echo Off
SetLocal EnableExtensions
:AskNum
Set "num=1"
Set /P "num=how many users?"
Set num | findstr.exe /RX "^num=[123456789][0123456789]*$" 1>NUL || GoTo AskNum
For /F %%G In ('powershell.exe "1..%num% | %% ToString User000"') Do Echo %%G
Pause
This script will not continue unless the end user inputs an integer, without a leading 0, and which is a minimum value of 1. Here you can modify the Echo command in Do to an alternative, for example net.exe User %%G /Add, or if you wish, to a parenthesized sequence of commands. In each case %%G will contain the returned string with the incremented three digits.This version prepends each three digit number sequence with an additional string, (User), but that can simply be deleted or replaced if/as required.
#ECHO OFF
SETLOCAL enabledelayedexpansion
SET /p "lastnum= How many numbers? "
SET /a lastnum+=1000
FOR /L %%e IN (1001,1,%lastnum%) DO SET /a num=%%e&ECHO !num:~-3!
GOTO :EOF
No need for complication

Count Directory Files then Test Numeric values

Using the code below I am able to count the number of files in a directory and call another batch file if the number of files in the directory equals (EQU or ==) say 20
When i use LSS i run into a few problems. The results are problematic and i am getting unexpected results depending on how many files are in the directory or the value of LSS
If for example i have 9 files in my directory and LSS set for say 15 the call command doesn't work.
Is there a way to fix this possible number Vs string issue. I have also tried using "" around the numbers but still no luck. Any help would be appreciated
#ECHO OFF
SETLOCAL
SETLOCAL ENABLEDELAYEDEXPANSION
SET count=0
for %%o IN (C:\test1\*.*) DO (
echo %%o
SET /A count=count + 1
)
echo %count%
IF %count% LSS 20 call RunAll.bat
ENDLOCAL ENABLEDELAYEDEXPANSION
ENDLOCAL
you setlocal enabledelayedexpansion but you do not use its functionality. It makes more sense to wrap your if in double quotes or square brackets.
Lastly, no need to call RunAll.bat just can it without call.
#echo off
setlocal enabledelayedexpansion
set count=0
for %%o in (F:\CSV\*) do (
echo %%o
set /A count=count + 1
)
echo !count!
if "!count!" LSS "20" RunAll.bat
endlocal enabledelayedexpansion

remove a particular filename from the output of for loop

I have various files date wise as:
cpms_2015_09_01.txt
lms_2015_07_10.txt
kmps_2015_10_07.txt
lmps_2015_10_07.txt
cpmgs_2015_10_07.txt
I wanted to remove from the "for loop" files of today's date name
How can I do this, I wrote a code for which I can store the file paths of all files in:
XCOUNT_1=D:\check\cpms_2015_09_01.txt ...etc
But, there shouldn't be no XCOUNT for today's file name like %_2015_10_07%
I am struck at this section of code pointed below
DO ( IF NOT "_%year%_%day%_%month%.txt"=="!FTRIM_%%J!"
My code is below
SETLOCAL ENABLEDELAYEDEXPANSION
setlocal
SET /A MAXJ=1
SET /A J=1
echo %DATE%
set year=%date:~-4,4%
set year=%year: =%
set month=%date:~7,2%
set month=%month: =%
set day=%date:~4,2%
set day=%day: =%
FOR /F "usebackq tokens=*" %%i IN (`DIR /S /B D:\check\*.txt`) DO ( IF NOT "_%year%_%day%_%month%.txt"=="!FTRIM_%%J!" (
SET XCOUNT_!J!=%%~i
SET FNAME_!J!=%%~ni
SET MAXJ=!J!
SET /A J+=1
SET FTRIM_!nxi!=%%~nxi:~-10,10%
PAUSE
)
)
C:\Users\pwatson\bin>type atest.bat
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET /A J=1
SET /A MAXJ=0
FOR /F "usebackq tokens=*" %%i IN (`DIR /S /B C:\Python27-32\*.exe`) DO (
SET XCOUNT_!J!=%%~i
SET MAXJ=!J!
SET /A J+=1
)
SET XCOUNT
This produces:
C:\Users\pwatson\bin>call atest.bat
XCOUNT_1=C:\Python27-32\python.exe
XCOUNT_10=C:\Python27-32\Lib\site-packages\pip\_vendor\distlib\t64.exe
XCOUNT_11=C:\Python27-32\Lib\site-packages\pip\_vendor\distlib\w32.exe
XCOUNT_12=C:\Python27-32\Lib\site-packages\pip\_vendor\distlib\w64.exe
XCOUNT_13=C:\Python27-32\Lib\site-packages\setuptools\cli-32.exe
XCOUNT_14=C:\Python27-32\Lib\site-packages\setuptools\cli-64.exe
XCOUNT_15=C:\Python27-32\Lib\site-packages\setuptools\cli-arm-32.exe
XCOUNT_16=C:\Python27-32\Lib\site-packages\setuptools\cli.exe
XCOUNT_17=C:\Python27-32\Lib\site-packages\setuptools\gui-32.exe
XCOUNT_18=C:\Python27-32\Lib\site-packages\setuptools\gui-64.exe
XCOUNT_19=C:\Python27-32\Lib\site-packages\setuptools\gui-arm-32.exe
XCOUNT_2=C:\Python27-32\pythonw.exe
XCOUNT_20=C:\Python27-32\Lib\site-packages\setuptools\gui.exe
XCOUNT_21=C:\Python27-32\Scripts\easy_install-2.7.exe
XCOUNT_22=C:\Python27-32\Scripts\easy_install.exe
XCOUNT_23=C:\Python27-32\Scripts\pip.exe
XCOUNT_24=C:\Python27-32\Scripts\pip2.7.exe
XCOUNT_25=C:\Python27-32\Scripts\pip2.exe
XCOUNT_3=C:\Python27-32\w9xpopen.exe
XCOUNT_4=C:\Python27-32\Lib\distutils\command\wininst-6.0.exe
XCOUNT_5=C:\Python27-32\Lib\distutils\command\wininst-7.1.exe
XCOUNT_6=C:\Python27-32\Lib\distutils\command\wininst-8.0.exe
XCOUNT_7=C:\Python27-32\Lib\distutils\command\wininst-9.0-amd64.exe
XCOUNT_8=C:\Python27-32\Lib\distutils\command\wininst-9.0.exe
XCOUNT_9=C:\Python27-32\Lib\site-packages\pip\_vendor\distlib\t32.exe
Getting these back into the parent environment is another issue. I hope that dbenham might respond.
First of all, you can't have all of that code on the same line like that unless you tell batch where one command stops and the next command begins. Secondly, the code you have will only work on the command prompt and not in a batch file, because you need two %s when using for loop variables inside of batch files. Third, set /a is only used for math; use a regular set command when storing a string value.
Finally (and most importantly), you need delayed expansion to properly iterate your counter variable inside of your for loop.
This batch script should work:
#echo off
setlocal enabledelayedexpansion
set J=1
for /R "D:\TEST" %%I in (*.txt) do (
set XCOUNT_!J!=%%I
set /a J+=1
)
If you want to exclude a specific file from the output, wrap the set code in an if statement.
#echo off
setlocal enabledelayedexpansion
set J=1
for /R "D:\TEST" %%I in (*.txt) do (
if not "%%~nxI"=="test.txt" (
set XCOUNT_!J!=%%I
set /a J+=1
)
)

Batch File - loop incrementing count in value not displaying correctly

I'm trying to read a file and output the lines of data into registry keys. The data collection works, but I don't understand the syntax required to increment the string values in the last loop.
#echo OFF
SETLOCAL DisableDelayedExpansion
FOR /F "usebackq skip=1 delims=" %%a in (`"findstr /n ^^ C:\GetSID.txt"`) do (
set "var=%%a"
SETLOCAL EnableDelayedExpansion
set "var=!var:*:=!" This removes the prefix
echo(!var:~76,63!>>C:\SIDoutput.txt
goto :EndLoop
)
:EndLoop
set /p SID= <C:\users\paintic\SIDoutput.txt
set KEY_NAME="HKEY_USERS\!SID!\Software\Microsoft\Windows NT\CurrentVersion\PrinterPorts"
set Counter=1
for /f %%x in (C:\users\paintic\Networkprinters.txt) do (
set "Line_!Counter!=%%x"
set /a Counter+=1
if !Counter!==3 (Echo %line_counter%)
)
set /a counter2=!counter!-3
set counter=1
The part below is what I can't get to work. I'm trying to write LINE_1, LINE_2 and LINE_3 values from the previous loop to increment via the loop below. So VALUENAME should equal LINE_1, TYPE should = LINE_2's value and DATA should = LINE_3 on the first run and keep going up by 1 until the loop finishes (end of the file read)
`for /L %%i in (1,1,%counter2%) do (
set ValueName=%Line_!counter!%
set /a counter+=1
set Type=%Line_!counter!%
set /a Counter+=1
set Data=%Line_!counter!%
set /a Counter+=1
echo !ValueName!
echo !Type!
echo !Data!
REG ADD %KEY_NAME% /v !ValueName! /t !Type! /d !Data! /f
)
ENDLOCAL
Pause`
On searching for errors in batch file it is always helpful to use in first line #echo on or remove #echo off or comment this line with rem to see what cmd.exe really executes.
Command line interpreter fails on lines with set VariableName=%Line_!counter!% as the interpreter does not know what to expand first. I think it is not possible to create dynamically the name of an environment variable and reference next the value of this environment variable. This approach most likely does not work ever.
However, what you want to achieve can be done much easier directly in second loop as the following example demonstrates:
#echo off
setlocal EnableDelayedExpansion
rem Create data for demo example.
set "KEY_NAME=HKEY_USERS\S-1-5-20\Software\Microsoft\Windows NT\CurrentVersion\PrinterPorts"
echo TestValue>"%TEMP%\Networkprinters.txt"
echo REG_SZ>>"%TEMP%\Networkprinters.txt"
echo Sample Data>>"%TEMP%\Networkprinters.txt"
echo AnotherValue>>"%TEMP%\Networkprinters.txt"
echo REG_DWORD>>"%TEMP%\Networkprinters.txt"
echo ^1>>"%TEMP%\Networkprinters.txt"
rem Now the loop follows which reads the data from the file line
rem by line and build the line for using command "reg.exe" to
rem add the data to registry of the user with the defined SID.
set Counter=1
for /f "usebackq delims=" %%x in ("%TEMP%\Networkprinters.txt") do (
if "!Counter!"=="1" (
set "ValueName=%%x"
) else if "!Counter!"=="2" (
set "ValueType=%%x"
) else (
set "ValueData=%%x"
rem Echo the command instead of really executing "reg.exe".
echo reg.exe ADD %KEY_NAME% /v "!ValueName!" /t !ValueType! /d "!ValueData!" /f
set Counter=0
)
set /a Counter+=1
)
rem Delete the text file created for demo example.
del "%TEMP%\Networkprinters.txt"
endlocal
This solution is much easier than what you have tried and can be maybe even more simplified.

batch programming

I am new in batch. Trying for some days to make something in batch but have a problem I cannot solve. I read a lot of your comments but did not find answer. Maybe you can help me?
The point is:
I input string from keyboard( e.g. 10 characters ). name of it is"allinputstring"
Calculate of length is ok ( by redirect in txt file and expand its bytes ). name "length"
Parse string in 10 pieces (strings) is ok.
So here is a problem, I want to echo these pieces, so I use next code, I use a counter to find out is the counter give me good count as output variable, and echo it to see on screen if it is good. Counter seems good, end echo of pieces strings is good enough. But I want to put in line 5. Variable count instead of "%%m", and cannot find a syntax way how to do it.
setlocal enabledelayedexpansion
for /l %%m in (1,1,!lenght!) do (
set /a count=0
set /a count=count+%%m
echo !count!!allinputstring:~%%m,1!
)
endlocal
please help me.
Try this:
#echo off &setlocal enabledelayedexpansion
set /a lenght=9
set "allinputstring=ABCDEFGHIJ"
for /l %%m in (0,1,%lenght%) do (
set /a count=0
set /a count+=%%m
echo !count! !allinputstring:~%%m,1!
)
endlocal
Output is:
0 A
1 B
2 C
3 D
4 E
5 F
6 G
7 H
8 I
9 J
#ECHO off
setlocal ENABLEDELAYEDEXPANSION
SET allinputstring=abcdefghijk
SET lenght=10
for /l %%m in (1,1,!lenght!) do (
set /a count=0
set /a count=count+%%m
FOR %%z IN (!count!) DO echo !count! !allinputstring:~%%z,1!
)
GOTO :eof
Does this do what you require?
So... to make COUNT show (I've assigned it to KOWNT, but the syntax endlocal&set count=%count% would assign it to COUNT instead)
I've changed the starting value of the FOR/L because character counting starts from character#0 in the string.
#ECHO off
setlocal ENABLEDELAYEDEXPANSION
SET allinputstring=abcdefghij
SET lenght=9
for /l %%m in (0,1,!lenght!) do (
set /a count=0
set /a count=count+%%m
FOR %%z IN (!count!) DO echo !count! !allinputstring:~%%z,1!
)
endlocal&SET KOWNT=%count%
ECHO Now KOWNT=%KOWNT% but count=%count% because we have exited the SETLOCAL
GOTO :eof
When the ENDLOCAL is encountered, the parser substitutes the CURRENT value of the variables in the line and THEN executes the line.
Hence, the line is executed as
endlocal&set KOWNT=9
since the value of count at the time is 9.
When the SETLOCAL is executed, all changes to the environment since the matching SETLOCAL are thrown away. The environment variables are restored to their state when the SETLOCAL was executed and count becomes empty again (as it was before the routine.) THEN the SET instruction is executed, which sets KOWNT to 9.

Resources