For loop statement in batch program repeats 5 times - for-loop

But I'm still having an issue with regards to the program I posted previously. I think there is a problem in my for loop statement because after I opened the file "passwords.csv", I noticed that the loop repeated 5 times.
The first record R_000100.pdf was initially assigned the password 8337, but repeated in other rows and reassigned with other random passwords. And when I tried to open the PDF file, it seems that the last random password assigned (which is 13429) was really its password, and not 8337.
What should I do to correct the program wherein after the all the PDF files have been combined and assigned with passwords, the program will already stop the loop and exit? Thus having only one entry in the output file "passwords.csv" and won't repeat 5 times.
Below is the complete batch program I accomplished, with the help of Peter Wright.
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
for /f "tokens=1,2 delims=ABCDEF_." %%i in ('dir *.txt *.pdf /b') do (
TXTtoPDF A_%%i.txt A_%%i.pdf -pps4 -pfs10.9
TXTtoPDF B_%%i.txt B_%%i.pdf -pps4 -pfs8.9
TXTtoPDF C_%%i.txt C_%%i.pdf -pps4 -plm50 -prm50 -pfs7.9
TXTtoPDF D_%%i.txt D_%%i.pdf -pps4 -plm60 -prm60 -pfs8.9
TXTtoPDF E_%%i.txt E_%%i.pdf -pps5 -pot -pfs10
TXTtoPDF F_%%i.txt F_%%i.pdf -pps5 -pot -pfs12
set pass=!random!
pdftk *%%i.pdf cat output PDF\R_%%i.pdf user_pw !pass!
echo %%i R_%%i.pdf !pass! >> passwords.csv
)
echo ***************************************************
echo * *
echo * PDF REPORTS SUCCESSFULLY GENERATED. *
echo * PLEASE TYPE EXIT AT COMMAND PROMPT. *
echo * *
echo ***************************************************
pause
exit

Easy, what you have to do is give the batch file the logic to realise which line it is up to.
Replace :
for /f "tokens=1,2 delims=ABCDEF_." %%i in ('dir *.txt *.pdf /b') do (
With :
set /a count=0
for /f "tokens=1,2 delims=ABCDEF_." %%i in ('dir *.txt *.pdf /b') do (
set /a count+=1
if !count! equ 1 (
Note : add an extra bracket when closing the for-loop for the if-loop
This way, it will count each line the for-loop parse's. If you want to set your password for the second or fifth line, replace if !count! equ 1 ( with if !count! equ 2 ( or if !count! equ 5 ( respectively.
It is useful to do this in all batch files when using for-loops. It is done by default when using an actual programming language.
Hope this helped.
Yours Mona

Related

Batch code to turn every line of text to a variable

So I need a code that will take a text file (we'll cal it list.txt) and turn every line into a variable.
To give some context, I have some file names listed in list.txt, which adds and deletes file names occasionally by user request. I want the user of this code to be able to select which document they'd like to open using variables.
For example, if list.txt looks like this
list.txt
loading.txt
test1.txt
test2.txt
test3.txt
test4.txt
Then I'd like an automatic variable for every .txt listed. I then would add a simple if statement to open the file matched with the variable.
Am I making this too complicated for myself or is this the only way to do this?
EDIT:
I am not attempting something like this:
type list.txt
echo.
echo.
set /p GROUPSELECT= Please type out the FULL name of the group listed:
CD %grouplist%
type %GROUPSELECT%
It will display the file contents, and then display the specific file chosen by the input. I'd think that the variable might be easier to do more with later though, just a thought.
Edit2
I tried this:
#Echo OFF
FOR /F "Usebackq Delims=" %%a IN (
"list.txt"
) DO (
set jim=%%a
)
echo %jim%
PAUSE
%jim% will only be the last line in the text file, so how do I make the next step into making them all different?
Give this a try. I have commented each line of code that should explain what it is doing. Let me know if you need any further explanation.
#echo off
REM FOR commnd is parsing the output of the FINDSTR commands.
REM First FINDSTR command is finding non empty lines in the file
REM Second Findstr command is assigning a number to each line of the file
REM The output is split into two tokens and the number is assigned to %%G and the line of the file to %%H
for /F "tokens=1* delims=:" %%G IN ('findstr /V "^$" list.txt ^|findstr /N ".*"') DO (
REM create a variable of the lines in the file
set "file%%G=%%H"
REM Create a menu of the lines in the file
echo %%G %%H
REM Get the number of lines in the output
set "num=%%G"
)
REM Ask user to chose a number
set /P "filenum=Chose a file number 1 to %num%:"
REM Need to enable delayed expansion to use array variables
setlocal enabledelayedexpansion
REM Check if they type in a correct number and display the file
IF DEFINED file%filenum% type !file%filenum%!
endlocal
pause
Is this the sort of thing you're looking for?
#For /F "Delims==" %%# In ('Set # 2^>Nul')Do #Set "%%#="
#For /F Tokens^=1*Delims^=[]^ EOL^= %%# In ('Type "file.txt"^|Find /V /N ""'
)Do #Set "#%%#=%%$"&Echo( %%#. %%$
:Opt
#Echo(
#Set /P "Opt=Choose a document to open>"
#Set #|Findstr /B "#%Opt%=">Nul||GoTo :Opt
#Call Start "" "%%#%Opt%%%"
Just change the name of the text file containing your list on line 2 as needed.
#TheBoy your question is confusingly framed. If you DO NOT want the example you put in the edit, then can you better explain what you DO want??
Do you want to say iterate over the list file, and create a choice screen?
#(SETLOCAL EnableDelayedExpansion
ECHO OFF
SET "_ChoiceList_File=C:\Admin\ChoiceFile.txt"
REM Full Character List to populate Choices
SET "_CharList=0 1 2 3 4 5 6 7 8 9 A B C D E F N X"
)
CALL :Main
( ENDLOCAL
EXIT /B 0
)
:Main
REM Now we can Do Our Choices btu lets do it in a Sub Function.
CALL :MakeChoice _ChoiceResult
ECHO.
ECHO The Index Chosen Was: %_Chosen%
ECHO The Result Matched is: "%_ChoiceResult%"
REM ECHO Here you output "%_ChoiceResult%"
TYPE "%_ChoiceResult%"
GOTO :EOF
:MakeChoice
cls
color 1A
SET %~1="
SET "_Choices="
SET "_Chosen="
SET "_Amount="
SET "_Choice.17.Value=Next Set!"
SET "_Choice.18.Value=EXIT!"
SET "_Choice_Show_Next="
echo. Pick a File:
echo.========================
REM Create Numbered Array of Choices and output Choices to the Screen
FOR /F "tokens=* usebackq" %%A IN ("%_ChoiceList_File%") DO (
SET /A "_Amount+=1"
SET "_Choice.!_Amount!.Value=%%A"
IF !_Amount! EQU 16 (
SET /A "_Amount+=2"
CALL :MakeChoice "%~1"
IF DEFINED _Chosen (
IF !_Chosen! NEQ 17 (
REM IF !_Chosen! NEQ 18 (
GOTO :EOF
REM )
)
SET "_Amount="
SET "_Chosen="
)
)
)
IF NOT DEFINED _Chosen (
SET /A "_Amount+=1"
SET "_Choice.!_Amount!.Value=!"
SET /A "_Amount+=1"
SET "_Choice.!_Amount!.Value=EXIT!"
CALL :MakeChoice "%~1"
)
GOTO :EOF
:MakeChoice
CLS
ECHO.
SET "_Temp="
SET "_Choices="
SET /A "_Skipline= !_Amount! - 1"
REM Create Choice List to Display only the choices needed.
FOR %%A IN (%_CharList%) DO (
SET /A "_Temp+=1"
IF !_Temp! LEQ !_Amount! (
IF !_Temp! EQU !_Skipline! (
ECHO.
ECHO.=============================
)
IF DEFINED _Choice.!_Temp!.Value (
SET "_Choices=!_Choices!%%A"
CALL ECHO. %%A : %%_Choice.!_Temp!.Value%%
)
)
)
ECHO.
CHOICE /C !_Choices! /N /M "What File do you want to choose? "
SET "_Chosen=%ERRORLEVEL%"
SET "%~1=!_Choice.%_Chosen%.Value!"
GOTO :EOF
)
You can try this:
#echo off
setlocal enabledelayedexpansion
set jim=
for /f "delims=] tokens=1*" %%a in ('find /v /n "" ^<list.txt') do (
set jim=!jim! %%b
)
echo Select a file from !jim!
set /p file=
type !file!
pause
This will read all lines from the list.txt and return them within a variable !jim!.

Result of each repeat of the loop to different file WIN BATCH

I would like to resolve simple problem - Saving to different file when loop repeats. I know im getting results because when I am doing >>file.txt
i am getting all restults into one file. It would be GREAT to save results to different files each time(and name this file by text from variable. but there is something wrong. It saves the results of last loop iteration.
#echo off
setlocal ENABLEDELAYEDEXPANSION
set vidx=0
for /F "tokens=1* delims=;" %%A in (list2.csv) do (
SET /A vidx=!vidx! + 1
set var!vidx!=%%A
rxrepl -f temp.txt -s "xNAMEx" -r "%%A">file___%var!vidx!%.txt
)
Try replacing this
file___%var!vidx!%.txt by this file___!var!!vidx!!!.txt
You don't need any variables to get the result you are looking for. Also, the * is usesless in "tokens=1*" if you never reference variable %%B. And "tokens=1" is the default. So all you need is:
for /F "delims=;" %%A in (list2.csv) do rxrepl -f temp.txt -s "xNAMEx" -r "%%A">"file___%%A.txt"
If you really want to build an "array" of var.N values, you can use FINDSTR to prefix each line with an incrementing number (line number).
for /F "tokens=1,2 delims=:;" %%A in ('findstr /n "^" list2.csv') do (
set "var.%%A=%%B"
set "var.cnt=%%A"
rxrepl -f temp.txt -s "xNAMEx" -r "%%B">"file___%%B.txt"
)
:: Display the "array" values
for /l %%N in (1 1 %var.cnt%) do echo var.%%N=!var.%%N!
Use just ...>"file___%%~A.txt" instead of erroneous >file___%var!vidx!%.txt
#ECHO OFF
SETLOCAL enableextensions enabledelayedexpansion
set vidx=0
for /F "tokens=1* delims=;" %%A in (list2.csv) do (
SET /A "vidx+=1"
set "var!vidx!=%%~A"
echo loopvar %%%% A=%%~A "file___%%~A.txt"
rem next line shows how to treat array-like names
call set "filenamepart=%%var!vidx!%%"
echo filenamepart=!filenamepart! "file___!filenamepart!.txt"
rem rxrepl -f temp.txt -s "xNAMEx" -r "%%A">"file___%%~A.txt"
)

Why isn't my BAT file variable being overwritten?

I have this block of code:
#ECHO OFF
SET "SRCFOLDER=C:\Users\MyUserName\Desktop\PhotoTests"
SET "TEMPCODE=Hi"
ECHO %TEMPCODE%
ECHO.
FOR /F "tokens=*" %%G IN ('DIR /B %SRCFOLDER%') DO (
ECHO %%G
CALL tooltipInfo.bat %%G 19 | FIND /C "Star" > test.txt
SET /P TEMPCODE=<test.txt
ECHO %TEMPCODE%
ECHO.
)
SET /P TEMPCODE=<test.txt
ECHO %TEMPCODE%
ECHO.
PAUSE
I'm confused by the output as I noticed that the variable in the FOR loop is not overwritten by what I think should be the content of "test.txt", which will vary each time the FOR loop runs.
For the purpose of this example, the file tooltipInfo.bat will echo a text string like "1 Star" or "3 Stars" based on the rating recorded in the file's properties. The FIND statement should result in a "0" or "1" being saved into the test.txt file.
The output is:
Hi
Canon_Locked.JPG
Hi
Nikon_Locked.JPG
Hi
0
Press any key to continue . . .
May I know why the TEMPCODE variable isn't being overwritten in the loop and retains the original value of "Hi". However in the final block of code, it was able to read and echo out the actual content of the file.
This is a common mistake when using FOR and parentheses. The problem is that by default every variable between ( and ) is evaluated when the line is first read, and then re-used for each iteration of the FOR.
If the variable changes during the loop (via SET), then you will need to change % to ! for variables inside the parentheses, and also turn on delayed expansion using setlocal
SETLOCAL enabledelayedexpansion
FOR /F "tokens=*" %%G IN ('DIR /B %SRCFOLDER%') DO (
ECHO %%G
CALL tooltipInfo.bat %%G 19 | FIND /C "Star" > test.txt
SET /P TEMPCODE=<test.txt
ECHO !TEMPCODE!
ECHO.
)

How to print a specific line (variable included) from a file (text) using cmd

I am really confused with something. I am making a batch file that can can display a specific line that I want. For example there is file hi.txt
Content of file -
ro.build.id=KOT49H
ro.build.display.id=XXX_ROM_v1
ro.build.version.incremental=eng.mudingyu.1408084583
ro.custom.build.version=XOLO_8x-1000_0815.v009
ro.internal.version=J608_XOLO_N1A_V0.8.7_S08015
ro.internal.version.rgk=J608_XOLO_N1A_V0.8.7_S08015
ro.build.version.sdk=19
ro.build.version.codename=REL
ro.build.version.release=4.4.4
ro.build.date=Fri Aug 15 14:39:45 CST 2014
ro.build.date.utc=1408084785
As here you can see the file content. Now say I want to print ONLY this piece of information on my screen when batch is executed
"4.4.4" from this line "ro.build.version.release=4.4.4"
I managed to pull of code for the 2nd line
ro.build.display.id=XXX_ROM_v1
When I execute batch I see this
XXX_ROM_V1
Code I used
set "build.prop="
for /F "skip=3 delims=" %%i in (WORKING_FOLDER\system\build.prop) do if not
defined build.prop set "build.prop=%%i"
echo.
echo "%build.prop%"
echo.
echo Enter the name you want to choose
set /p name=
echo Backing up old build.prop...
md C:\Kitchen\temp
copy C:\Kitchen\WORKING_FOLDER\system\build.prop C:\Kitchen\temp
cd C:\Kitchen\temp
cd C:\Kitchen\WORKING_FOLDER\system
build.prop.new (
for /f "tokens=1* delims==" %%A in (build.prop) do (
if "%%A" == "ro.build.display.id" (
echo ro.build.display.id=%name%
) else (
echo %%A=%%B
)
)
)
move /y build.prop.new build.prop >nul
build.prop.new (
for /f "tokens=1* delims==" %%A in (build.prop) do (
if "%%A" == "ro.build.id" (
echo ro.build.id=%name%
) else (
echo %%A=%%B
)
)
)
move /y C:\Kitchen\temp\build.prop.new
C:\Kitchen\WORKING_FOLDER\system\build.prop >nul
echo Changed value of ro.build.display.id to " %name% "
echo.
set "build.prop="
for /F "skip=3 delims=" %%i in (WORKING_FOLDER\system\build.prop) do if not
defined build.prop set "build.prop=%%i"
echo In build.prop now the current name of ROM is
echo.
echo Current ROM Name = %name%
Here as you see in first line I print the name using the line command function and also took input from user to change the name so it became easy to print the file name but in some other files the line "ro.build.display.id" is not always on 4th.
So my question is what logic or whatever can be done in order to print the particular term on screen that I wish to print without prompting user to enter new file name just print that specific piece of information
eg The OUTPUT I want
The Android version is "4.4.4"
EG Say I want to print "4.4.4" only from the file above
how can I do it?
Using findstr or anything please help really appreciated.
whew - that was a lot to read for a quite simple question.
for /f "tokens=2 delims==" %%i in ('find "ro.build.version.release" hi.txt') do set release=%%i
echo The Android version is "%release%"
Find the correct line and tokenize it with = as delimiter.

Batch Scripting:search file, extract numbers, and copy into new file

I'm new to batch scripting and have a question. I was wondering if it's possible to search a .txt file by requirements and take data specified and copy into a new .txt file?
Like if I have 50 lines with 9 digit numbers and a bunch of other crap I don't need after them can I say,
"For any line beginning with a 1,2,3,4,5,6,7,8,or 9...take the first 9 digits and copy them into a new file, for all lines in the file???"
I thought this would be easier than trying to delete all the other stuff. Let me know if you know anything about how to do this! Thanks.
Here's an example of what one line looks like:
123456789#example
and I just need to extract the 9 digit numbers from about 50 lines of this.
You can use FINDSTR to filter out all lines that do not start with 9 digits. Then FOR /F can read the result, line by line. A variable is set, and a substring operation preserves just the first 9 digits.
#echo off
setlocal enableDelayedExpansion
(
for /f %%A in (
'findstr "^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]" yourFile.txt'
) do (
set "ln=%%A"
echo !ln:~0,9!
)
)>newFile.txt
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
(
FOR /f "delims=" %%a IN (q24824079.txt) DO (
SET "line=%%a"
REM set DIGITS to the first 9 characters of LINE
SET "digits=9!line:~0,9!"
FOR /L %%z IN (0,1,9) DO SET "digits=!digits:%%z=!"
IF NOT DEFINED digits ECHO(!line:~0,9!
)
)>newfile.txt
GOTO :EOF
I used a file named q24824079.txt containing data for my testing.
Produces newfile.txt
You did not specfy what to do if the line was all-digits but has fewer than 9 characters. I chose to report that line.
Hopefully this helps getting the job done:
#echo off
setlocal enabledelayedexpansion
for /f %%e in (emails.txt) do (
echo Email: %%e
for /f "delims=# tokens=1" %%b in ("%%e") do (
set BEGIN=%%b
echo Name: !BEGIN!
set FIRST=!BEGIN:~0,1!
echo First char: !FIRST!
set /a NUMERIC=!FIRST!+0
echo Converted to number: !NUMERIC!
if !FIRST!==!NUMERIC! echo Yippieh!
echo.
)
)
Instead of echo Yippieh! append the email (%%e) to a file, e.g. like
echo %%e >> output.txt

Resources