FINDSTR in FOR loop with variables as strings (Batch File) - variables

It's my first post here, unfotrtunately question to you instead of help.
I'm writing small program which moves text and pdf files when string is found in text file.(1.txt, 1.txt.pdf ...) It was working very good when i had variables manually set in batch like this :
set c1=xxx
set p1=c:\test\xxx\
set c2=yyy
set p2=c:\test\yyy\
FOR /f "tokens=*" %%A IN ('FINDSTR /i /m "%c1%" "c:\test\*.txt"') DO (
IF "%ERRORLEVEL%"=="0" MOVE %%A "%p1%">nul
MOVE %%A.pdf %p1%
FOR /f "tokens=*" %%A IN ('FINDSTR /i /m "%c2%" "c:\test\*.txt"') DO (
IF "%ERRORLEVEL%"=="0" MOVE %%A "%p2%">nul
MOVE %%A.pdf %p2%
Now I'm trying to use input file with variables :
for /F "delims=^ tokens=1,2" %%A in (c:\test\db\input.cdb) do (
SET /A vidx=!vidx! + 1
set c!vidx!=%%A & set p!vidx!=%%B
It works good, but the problem starts when I try to use for loop for all this variables. Literally search for all (c1,c2,c3...) variables and move them to (p1,p2,p3,...) paths.
Input.cdb looks like this :
xxx ^ c:\test\xxx
yyy ^ c:\test\yyy
Code:
setlocal ENABLEDELAYEDEXPANSION
set vidx=0
for /F "delims=^ tokens=1,2" %%A in (c:\test\db\input.cdb) do (
SET /A vidx=!vidx! + 1
set c!vidx!=%%A & set p!vidx!=%%B
FOR /f "tokens=*" %%D IN ('FINDSTR /i /m "%c!vidx!%" "c:\test\*.txt"') DO (
IF "%ERRORLEVEL%"=="0" MOVE %%D "%p!vidx!%">nul
MOVE "%%D.pdf" "%p!vidx!%"
ECHO %%D File is being procesed now
)
)
I don't know why this code doesn't work, maybe because there is loop inside loop?
Or how to create loop to do the same from 0 to how many lines of variables has been read from input.cdb?
I've tried to run this in separate for loop with temporary variable but it's still not using my string and path variables.
Thank you in advance for any help!
With Regards
Blackfusion

Ugh. More than one problem, and what is the appropriate solution?
First item is a matter of logical design. Let's assume that the batch worked as intended. c!vidx! would be set to %%A and p!vidx! to %%B, so unless there's some unpublished use for c... and p... then you could simply substitute as follows:
setlocal ENABLEDELAYEDEXPANSION
for /F "delims=^ tokens=1,2" %%A in (c:\test\db\input.cdb) do (
FOR /f "tokens=*" %%D IN ('FINDSTR /i /m "%%A" "c:\test\*.txt"') DO (
IF "%ERRORLEVEL%"=="0" MOVE %%D "%%B">nul
MOVE "%%D.pdf" "%%B"
ECHO %%D File is being procesed now
)
)
Now - there's a common fundamental misconception about %var% where var is any variable (including %ERRORLEVEL% and %C!vidx!%...) - a %VAR% occurring in a compound statement (or "block") - within the parentheses if a FOR...DO (in here) or IF...(here) ELSE (or here) is replaced with that variable's value at the time the outermost statement is parsed - before it is executed. If delayedexpansion is invoked (as you have) then !var! refers to the run-time value and %var% to the parse-time value.
Hence, if "%errorlevel%"=="0" would be evaluated according to the state of errorlevel when the for...%%A was parsed, not the value as set by the findstr.
This can be corrected by
setlocal ENABLEDELAYEDEXPANSION
for /F "delims=^ tokens=1,2" %%A in (c:\test\db\input.cdb) do (
FOR /f "tokens=*" %%D IN ('FINDSTR /i /m "%%A" "c:\test\*.txt"') DO (
IF not errorlevel 1 MOVE %%D "%%B">nul
MOVE "%%D.pdf" "%%B"
ECHO %%D File is being procesed now
)
)
Where IF not errorlevel 1 is interpreted as if the CURRENT (run-time) errorlevel is NOT (1 or greater than 1)

Related

Iterating through a folder batch

I'm somewhat new to batch, and I'm trying to build a program in batch that renames all the files to numbers, but it just doesn't work, I have no idea what the problem is here, I hope someone can help me find it.
#echo off
SET x=0
for %%I in (*) do(
SET /a x+=1
REN %%I %x%
)
pause
How about this quick one ?
I provided an if condition to prevent the batch from renaming itself in case you have it in the same directory where your files are. (e.g. while testing)
You might want to change this according to your needs...
numberize.bat
#ECHO OFF
SetLocal EnableDelayedExpansion
set /a x=0
for %%i in (*) do ( call :doit "%%i" )
goto eof
:doit
if /I %1 NEQ "numberize.bat" (
set /a "x=x+1"
ren %1 %x%
)
EXIT /B
:eof
EndLocal

for /f loop "tokens and delimiters" didn't work with variables (batch file)

recently I was making a batch file I ran into a problem,
when I made a for /f loop, I used a variable in "tokens", like this example:
for /f "delims= tokens=!count2!" %%a in ('type test.txt 2^>nul') do (
like you can see, i have the variable !count2!, in the loop.
and when i tested it, it displayed !count2!" was unexpected at this time. And I dont know why?
can anyone help?
here is the full code of what I have tried:
#echo off
setlocal enableextensions enabledelayedexpansion
set "count1=0"
set "count2=0"
for /l %%b in (1 1 10) do (
set /a "count2+=1"
set /a "count1+=1"
for /f "delims= tokens=!count2!" %%a in ('type test.txt 2^>nul') do (
set "str!count1!=%%a"
)
)
echo !str1! !str2! !str3! !str4!
pause
by the way, test.txt contains test hello # ###
and, I want to set test, hello, # and ### as their own variable (str1, str2, str3 and str4).
and yes I have tried to do it with % instead of !
tell me if i wasn't clear enough!
thanks for all help :)
why bothering with tokens?
#echo off
setlocal enabledelayedexpansion
set /a count=0
for /f "delims=" %%i in (test.txt) do for %%j in (%%i) do (
set /a count+=1
set str!count!=%%j
)
set str

Assign variables in batch script

I'm new in Windows batch programming and I have found problems in the variable assignment. This is my code:
#echo off
setlocal enabledelayedexpansion
set Video=1
set FILEMEDIA=outputMedia.txt
for /f %%a in (%FILEMEDIA%) do (
set /a Video=%Video%+1
#echo Video
set file=%%a
#echo file
)
If FILEMEDIA has two lines I would like to obtain Video=2 and the line in file variable. However, at the end I obtain Video=1 and an error when I tried to print file (echo is off).
Some kind of duplicate with How do I increment a DOS variable in a FOR /F loop?
Variables that should be delay expanded are referenced with !VARIABLE! instead of %VARIABLE%.
#echo off
setlocal enabledelayedexpansion
set Video=1
set FILEMEDIA=outputMedia.txt
for /f %%a in (%FILEMEDIA%) do (
set /a Video+=1
#echo !Video!
set file=%%a
#echo file
)
endlocal

incrementing a counter variable inside a FORLOOP

why is the variable "number" not increasing when the FOR loop goes over it again?
setLocal EnableDelayedExpansion
for /f "tokens=* delims= " %%a in (input.txt) do (
set /a N+=1
set /a number=!number!+1
echo %%a !number!.jpg >output.txt
)
OK, try this please:
#echo off &setLocal EnableDelayedExpansion
(for /f "tokens=* delims= " %%a in (input.txt) do (
set /a N+=1
set /a number=!number!+1
echo %%a !number!.jpg
))>output.txt
In case of redirection you need >>output.txt or a code block (parentheses) and >output.txt.
First of all I don't recommend you to enable expansion of variables when you are working with filenames, use it only if you really know what means enabling the delayedexpansion, the benefits (improved velocity) and the negatives (missing characters).
Also you are assigning a value for the variable "N" but you don't use that var.
Here is the code:
#echo off
(for /f "usebackq tokens=* delims= " %%a in ("input.txt") do (
Set /A Number+=1
Call Echo %%a %%number%%.jpg
))>"Output.txt"
Pause&Exit
You should try
setLocal EnableDelayedExpansion
for /f "tokens=* delims= " %%a in (input.txt) do (
set /a N++
set /a number=!number!+1
echo %%a !number!.jpg >output.txt
)
EDIT
Or try:
setLocal EnableDelayedExpansion
for /f "tokens=* delims= " %%a in (input.txt) do (
set /a N++
set /a number=!number!++
echo %%a !number!.jpg >output.txt
)
Or maybe that ++ isnt even supported by what you are using to program this. Let me know though! Shadowpat

How to delete a line of a text file, given the line number using batch (.bat) script?

I want to write a batch script where the user can enter the line number and the script will delete that line of a text file.
Eg: tmp.txt
1. aaa
2. bbb
3. ccc
4. ddd
I want when i execute my script and user inputs 3, the tmp.txt to be
1. aaa
2. bbb
4. ddd
I am trying something like this:
#ECHO OFF
SET /P LINENUMBER=Enter the Line No:
FOR /F "tokens=1* delims=[]" %%a IN ('FIND /n /v "" ^< tmp.txt') DO (
IF %%a equ %LINENUMBER% (
????????????????????
)
)
You cannot modify the file directly. You must create a new file with the desired content and then replace the original file with the new file.
You create the new file by redirecting output and ECHOing the desired content. I use ECHO(%%b in case %%b is empty because the line was blank. ECHO %%b would produce ECHO is off. if b is empty. Most people use ECHO., but that can fail under esoteric conditions. ECHO( will never fail.
You use MOVE to replace the original file with the new.
You can eliminate the need to check for the number within your FOR /F loop by using FINDSTR after FIND to filter out the unwanted line.
Note that your code, as written so far, will strip any leading [ and ] characters from each line. Because the line filter is applied before the FOR iteration, you can improve the situation slightly by setting DELIMS to ] only.
#ECHO OFF
SET /P LINENUMBER=Enter the Line No:
>tmp.txt.new (
FOR /F "tokens=1* delims=]" %%a IN (
'FIND /n /v "" ^<tmp.txt^|FINDSTR /VLB "[%LINENUMBER%]"'
) DO ECHO(%%b
)
>nul MOVE /y tmp.txt.new tmp.txt
If any of your original lines already begin with ] then you can use FINDSTR instead of FIND to introduce the line number. That uses nn: format instead of [nn]. This solution will strip leading : from your lines.
#ECHO OFF
SET /P LINENUMBER=Enter the Line No:
>tmp.txt.new (
FOR /F "tokens=1* delims=:" %%a IN (
'FINDSTR /n "^" tmp.txt^|FINDSTR /VLB "%LINENUMBER%:"'
) DO ECHO(%%b
)
>nul MOVE /y tmp.txt.new tmp.txt
If your text file contains lines that begin both with : and ] then you can't use FOR /F to parse out the line number. Instead you use search and replace. Delayed expansion is toggled on and off within the loop to protect any ! that may exist in the file.
#ECHO OFF
setlocal disableDelayedExpansion
SET /P LINENUMBER=Enter the Line No:
>tmp.txt.new (
FOR /F "delims=" %%a IN (
'FINDSTR /n "^" tmp.txt ^| FINDSTR /VLB "%LINENUMBER%:"'
) DO (
set "ln=%%a"
setlocal enableDelayedExpansion
echo(!ln:*:=!
endlocal
)
)
>nul MOVE /y tmp.txt.new tmp.txt
try out this:
#echo off & setlocal
set "InFile=Z:\Text.txt"
set "OutFile=Z:\Erg.txt"
set /p LineToDelete=
if exist "%OutFile%" del "%OutFile%"
for /f "tokens=1* delims=:" %%i in ('findstr /n $ "%InFile%"^|findstr /b "%LineToDelete%:"') do findstr /v /b /c:"%%j" "%InFile%">>"%OutFile%"