Windows Batch File can't use variable in for syntax - windows

I want to use a variable skip parameter in for loop, but it won't let me do it.
Here is my code
#echo off
setlocal ENABLEDELAYEDEXPANSION
set /p testcase=<testcases.txt
set /a end=%testcase%*13
for /L %%P IN (1,13,%end%) DO (
set skip=skip=%%P
echo !skip!
set vidx=0
for /f "%skip%" %%A in (testcases.txt) do (
set /a vidx=!vidx! + 1
set var!vidx!=%%A
)
)
Here skip is skip=1, but it doesn't skip any line. When I replace it with skip=1. then it works fine, but I want to skip variable no. of lines in each iteration. Please help.

I think with this logic the only option is a subroutine:
#echo off
setlocal ENABLEDELAYEDEXPANSION
set /p testcase=<testcases.txt
set /a end=%testcase%*13
for /L %%P IN (1,13,%end%) DO (
set skip=skip=%%P
echo !skip!
set vidx=0
call :innerFor %%P
)
exit /b 0
:innerFor
for /f "skip=%~1" %%A in (testcases.txt) do (
set /a vidx=!vidx! + 1
set var!vidx!=%%A
)
exit /b 0
parametrization of FOR /F options is a little bit tricky..
Though I have no the content of your files I cant test if this works correctly .

Related

Count the underscores in the Filename with a bat

I have searched this everywhere and I didn't found it, so what I want to do is simple, I want to count the underscores in a filename and put it in a variable to later use it.
Is there any simple batch code to do it ?
#echo off
setlocal enabledelayedexpansion
set filename=__example_file.bin_
set cnt=0
set pos=0
:loop
if "!filename:~%pos%,1!"=="_" set /a cnt=%cnt%+1
set /a pos=%pos%+1
if not "!filename:~%pos%,1!"=="" goto loop
echo Count: %cnt%
That code is pretty ugly but I can't find a better way so far.
A different method to count underscores (or more exact elements separated by an underscore)
is to use self expanding code:
:: Q:\Test\2017\08\28\SO_45917406.cmd
#echo off & setlocal enabledelayedexpansion
set "FileName=example_file_name_20170828_181000.txt"
Set i=1&Set "FileName[!i!]=%FileName:_="&Set /a i+=1&Set "FileName[!i!]=%"
Echo Counted %i% underscore separated elements
Set FileName
Sample output:
> Q:\Test\2017\08\28\SO_45917406.cmd
Counted 5 underscore separated elements
FileName=example_file_name_20170828_181000.txt
FileName[1]=example
FileName[2]=file
FileName[3]=name
FileName[4]=20170828
FileName[5]=181000.txt
This solution is inspired from #xmcp :
#echo off
Rem The srting to count in the filename is the underscrore "_"
Rem we can of course set another one ;)
set "MyString=_"
setlocal enabledelayedexpansion
#for /f "delims=" %%a in ('Dir /b "%userprofile%\Desktop"') do (
set "filename=%%a"
set /a "cnt=0"
set /a "pos=0"
Call:Counting_String "!filename!" "%Mystring%"
)
pause & exit
::*********************************************************
:Counting_String <filename> <MyString>
set "filename=%~1"
set "string=%~2"
if /I "!filename:~%pos%,1!"=="%Mystring%" set /a cnt+=1
set /a pos+=1
if not "!filename:~%pos%,1!"=="" goto Counting_String
echo !filename!: [!cnt!] "%Mystring%"
exit /b
::*********************************************************

how to compare numeric variables in batch files

why doesn't this work?
SET FIRST=""
SET COUNT=0
FOR %%F IN (dir *.png) DO (
IF %COUNT% NEQ 0 GOTO _skip
SET FIRST=%%F
:_skip
ECHO "%%F",
SET /A COUNT=COUNT+1
)
It sets FIRST to the last *.png because the IF condition fails, because COUNT - although is incremented by set /A, the IF %COUNT% doesn't ever work. Very frustrating.
Don't need to count, just do goto skip after echo line.
#echo off
for /f "delims=" %%f in ('dir /b *.png') do (
rem :: you can use "echo %%f" instead of "set first=%%f"
set first=%%f
goto _skip
)
:_skip
echo %first%
you mixing two things to scan folder.
Here is the second way:
#echo off
for %%f in (*.png) do (
set first=%%f
goto _skip
)
:_skip
echo %first%
exit /b 0
If you need absolutely to count, here is the way to skip with count. As stated in comment, you need to enable delayedExpansion
#echo off
set count=1
for %%f in (*.png) do (
set first=%%f
setlocal enabledelayedexpansion
if "!count!"=="1" goto _skip
endlocal
set /a count+=1
)
:_skip
echo !first!

Batch: Replacement for goto loop

When I'm writing batch programs I tend to create a goto loop to set and display things.
Example:
#echo off & setlocal enabledelayedexpansion
:loop
if !num! GTR !max!
set /a "num=num+1"
echo display!num! = !display%num%!
goto :loop
I had a feeling that I can replace this with a for loop, but I had no success creating one that can replace the loop above. Does anyone know?
You can use a for /L loop.
for /L %%A in (!num!,1,!max!) do echo display%%A = !display%%A!
Where !num! is your starting number, !max! is your ending number, and 1 means count up by ones.
#echo off
setlocal enableextensions enabledelayedexpansion
rem Set limits
set /a "num=1", "max=10"
rem Prepare a set of variables to test
for /l %%a in (%num% 1 %max%) do set "display%%a=!random!"
rem Show the variables contents
for /l %%a in (%num% 1 %max%) do echo display%%a=!display%%a!

Batch encoding text files

I have this code to read a text file.
#ECHO OFF
SetLocal EnableDelayedExpansion
for /f "delims=" %%x in ('type text.txt') do (
set "Var=%%x"
ECHO !Var!
)
pause
My question is that if i could advance every char in the file by 20 places like "a" would be "t". it can have numbers and symbols too. the txt file is 400 line long and there is between 1 and 120 char per line. does any one know how i could do this.
Sorry, this will not handle all the posibilities, but
#echo off
setlocal enableextensions disabledelayedexpansion
call :setTables
set "inputFile=inputFile.txt"
for /f "usebackq delims=*" %%a in ("%inputFile%") do (
set "data=%%a"
call :handleProblems
set "out="
setlocal enabledelayedexpansion
for /f "delims=" %%b in ('cmd /v:off /q /u /c "echo(!data!"^|more') do (
if defined "%%b" (
set "out=!out!!"%%b"!"
) else (
set "out=!out!%%b"
)
)
echo(!out!
endlocal
)
exit /b
:handleProblems
set "data=%data:!=~%"
set "data=%data:<=^<%"
set "data=%data:>=^>%"
set "data=%data:&=^&%"
set "data=%data:|=^|%"
set "data=%data:)=^)%"
exit /b
:setTables
set ""a"=t"
set ""b"=u"
set ""c"=v"
set ""d"=w"
set ""e"=x"
set ""f"=y"
set ""g"=z"
set ""h"=a"
set ""i"=b"
set ""j"=c"
set ""k"=d"
set ""l"=e"
set ""m"=f"
set ""n"=g"
set ""o"=h"
set ""p"=i"
set ""q"=j"
set ""r"=k"
set ""s"=l"
set ""t"=m"
set ""u"=n"
set ""v"=o"
set ""w"=p"
set ""x"=q"
set ""y"=r"
set ""z"=s"
set ""~"=!"
set ""^&"=&"
exit /b
Use GnuSed and the "y/abc/tuv/" transliteration command which would replace a with t, b with u and c with v
This syntax works - just extend the character sets:
sed "y/abc/tuv/" "file.txt" >"newfile.txt"

Reading a text file line by line and storing it in an array using batch script

I want to read a text file and store each line in an array. When I used the code below, "echo %i%" is printing 0 every time and only array[0] value is getting assigned. But in "set n=%i%",n value is assigned as the last incremented I value.Also "#echo !array[%%i]!" is printing like !array[0]! instead of printing the value. Is there any syntax error in the code?
set /A i=0
for /F %%a in (C:\Users\Admin\Documents\url.txt) do (
set /A i+=1
echo %i%
set array[%i%]=%%a
)
set n=%i%
for /L %%i in (0,1,%n%) do #echo !array[%%i]!
Here's a method that is useful at times and very similar to your code:
#echo off
set "file=C:\Users\Admin\Documents\url.txt"
set /A i=0
for /F "usebackq delims=" %%a in ("%file%") do (
set /A i+=1
call echo %%i%%
call set array[%%i%%]=%%a
call set n=%%i%%
)
for /L %%i in (1,1,%n%) do call echo %%array[%%i]%%
#echo off &setlocal enabledelayedexpansion
for /F "delims=" %%a in (C:\Users\Admin\Documents\url.txt) do (
set /A count+=1
set "array[!count!]=%%a"
)
for /L %%i in (1,1,%count%) do echo !array[%%i]!
Inside a code block you need delayed expansion and !variables!.
Read set /? description about environment run-time linking. When you are using %i% inside for - it is pre-expanded before for execution. You need to use !i! instead.
#ECHO OFF
SETLOCAL
FOR /f "tokens=1*delims=:" %%i IN ('findstr /n /r "$" url.txt') DO SET max=%%i&SET array[%%i]=%%j
FOR /l %%i IN (1,1,%max%) DO CALL ECHO(%%array[%%i]%%
GOTO :EOF
provided no line begins ":"

Resources