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
Related
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
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
)
I have a folder with 460 images with 23 per person in the format: image_0001.jpg to image_0460.jpg.
What is the batch command to rename them in the form 01-01.jpg to 01-23.jpg for a person and thus the entire database upto 20-23.jpg?
[EDIT]
I came across:
#echo off & setlocal EnableDelayedExpansion
set a=1
for /f "delims=" %%i in ('dir /b *') do (
if not "%%~nxi"=="%~nx0" (
ren "%%i" "!a!"
set /a a+=1
)
)
I could not find a way to use loop variables to do the same. Is there a way to use loop variables or is there another way?
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\sourcedir"
SET /a filenum=10000
FOR /L %%a IN (1,1,20) DO (
FOR /L %%b IN (1,1,23) DO (
SET /a filenum+=1
SET /a newnum=10000+%%b+(%%a*100^)
ECHO(REN "%sourcedir%\image_!filenum:~-4!.jpg" "!newnum:~1,2!-!newnum:~-2!".jpg
)
)
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances.
The required REN commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(REN to REN to actually rename the files.
The issue is one of leading zeroes, hence invoke delayedexpansion and calculate using 10000+a significant number, then substring.
The rest is simply a matter of mathematics.
This method use the % (modulus or remainder) operator to count in groups of 23: the image=(image+1)%23 part vary image variable from 0 to 22 and repeat this count. imgaux=101+image vary imgaux from 101 to 123 and just the last two digits are used in the ren command. Finally, person+=!image increment person variable each time that image is zero.
#echo off
setlocal EnableDelayedExpansion
set /A person=100, image=-1
for %%a in (*.jpg) do (
set /A "image=(image+1)%%23, imgaux=101+image, person+=^!image"
ECHO ren "%%a" "!person:~1!-!imgaux:~1!.jpg"
)
Note that in this method the number of persons doesn't need to be known in advance.
I want to be able to get the next argument to compare to the current argument. So when the argVec is equal to "--define", I want to echo the next argument. I get the result "y" instead of "delivery".
My input is:
Cmd version version1 --define delivery
set inputArg=%*
setlocal enabledelayedexpansion
set Count=0
for %%x in (%inputArg%) do (
set /A Count+=1
set "argVec[!Count!]=%%~x"
)
for /L %%i in (1,1,%Count%) do echo %%i- !argVec[%%i]!
for /L %%x in (1,1,%Count%) do (
set /A y=%%x+1
#echo !y!
#echo !argVec[%%x]!
if "!argVec[%%x]!"=="--define" (
#echo !argVec[!y!]!
)
)
endlocal
When I added #echo off to the top of your script and ran it, I got the following output:
1- version1
2- --define
3- delivery
2
version1
3
--define
y
4
delivery
If I understand you correctly, the problem is the y on the third line from the bottom.
The reason you are getting y is because of #echo !argVec[!y!]!. This tokenizes as #echo, !argVec[!, y, !]!, which means "echo the contents of the !argVec[! variable, then echo y, then echo the contents of the ] variable. Since you don't have an !argVec[! variable or a ] variable, this reduces to "echo y".
To fix it, there is lots of good information at this SO answer. For your purposes, the important part of that post is this:
To get the value of an element when the index change inside FOR/IF enclose the element in double percents and precede the command with call.
Here is a version of your script that I think does what you want it to do:
#echo off
set inputArg=%*
setlocal enabledelayedexpansion
set Count=0
for %%x in (%inputArg%) do (
set /A Count+=1
set "argVec[!Count!]=%%~x"
)
for /L %%i in (1,1,%Count%) do echo %%i- !argVec[%%i]!
for /L %%x in (1,1,%Count%) do (
set /A y=%%x+1
#echo !y!
#echo !argVec[%%x]!
if "!argVec[%%x]!"=="--define" (
#call echo %%argVec[!y!]%%
)
)
endlocal
That prints:
1- version1
2- --define
3- delivery
2
version1
3
--define
delivery
4
delivery
I realize that echoing to the screen is probably not your final goal, so when you modify the script to do what you really want it to do, remember to use double percents around the whole "array", exclamation points around the index, and precede your command with call.
For example, if you want to add a compare condition, then set the contents of argVec[y] to a temporary variable from a call, and then use the temporary variable in your if, like this:
#echo off
set inputArg=%*
setlocal enabledelayedexpansion
set Count=0
for %%x in (%inputArg%) do (
set /A Count+=1
set "argVec[!Count!]=%%~x"
)
for /L %%i in (1,1,%Count%) do echo %%i- !argVec[%%i]!
for /L %%x in (1,1,%Count%) do (
set /A y=%%x+1
#echo !y!
#echo !argVec[%%x]!
#call set tmpvar=%%argVec[!y!]%%
if "!tmpvar!"=="--define" (
echo "found it"
)
)
endlocal
Output of the latest:
1- version1
2- --define
3- delivery
2
version1
"found it"
3
--define
4
delivery
You can not "nest" delayed expansions this way:
#echo !argVec[!y!]!
There are several ways to solve this problem, that are described here; the most efficient one is this:
for %%y in (!y!) do #echo !argVec[%%y]!
EDIT: Additional request stated in comment solved.
You may use the same method to get the value of argVec[!y!] and use it in any way you wish. For example:
for %%y in (!y!) do if "!argVec[%%y]!"=="delivery" echo true1
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.