I was trying to count the number of lines in a file using batch file (windows xp sp3).
Here is my code:
#echo off
set line=0
FOR /F "usebackq delims=" %%a in (foo) do (
set /A line+=1
echo line count: %line%
)
echo number of lines: %line%
Although it is counting the lines correctly, but the echo output isn't what I am expecting. I think this has some thing to do with delayed expansion of variable and so I tried SetLocal EnableDelayedExpansion as well, but that's also not working.
here is the output that I am getting:
C:\fiddle\temp>a.bat
line count: 0
line count: 0
line count: 0
line count: 0
line count: 0
number of lines: 5
What's wrong in here?
FYI: I got into this while looking for an answer for THIS question.
Add this line:
SETLOCAL ENABLEDELAYEDEXPANSION
Change this line:
echo line count: %line%
to this:
echo line count: !line!
So, the entire script will look like this:
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set line=0
FOR /F "usebackq delims=" %%a in (foo) do (
set /A line+=1
echo line count: !line!
)
echo number of lines: %line%
the batch script I use to count number of lines is the following. call it from the command line with your input file as parameter.
#echo off & setLocal EnableDELAYedeXpansion
for /f "tokens=1 delims=[]" %%a in ('find /v /c "" ^< %1') do (
echo %~n1 %%a
)
Related
i have a text file file.txt with the content:
%hello%
If i've set hello to "holi" is there any way I can type file.txt and resolve the variable content?
Maybe it's archivable piping to echo but
type file.txt | echo
Is not working for me.
Any help will be apreciated.
Thanks
Assuming there are no blank lines that need to be preserved
for /f usebackq^ delims^=^ eol^= %%A in ("yourFile.txt") do call echo(%%A
If there are blank lines, but no line begins with :, then
for /f "delims=: tokens=1*" %%A in ('findstr /n "^" "yourFile.txt"') do call echo(%%B
If there are blank lines, and some lines begin with :, and there are no ! literals
setlocal enableDelayedExpansion
for /f "delims=" %%A in ('findstr /n "^" "yourFile.txt"') do (
set "ln=%%A"
call echo(!ln:*:=!
)
If there are blank lines and some lines begin with :, and there are ! literals
for /f "delims=" %%A in ('findstr /n "^" "yourFile.txt"') do (
setlocal enableDelayedExpansion
set "ln=%%A"
call echo(!ln:*:=!
endlocal
)
All of the above use CALL, which slows things down considerably. The solution is faster if you put !hello! in your file instead of %hello%, and then you can rely on delayed expansion to expand the variable.
If no blank lines
setlocal enableDelayedExpansion
for /f usebackq^ delims^=^ eol^= %%A in ("yourFile.txt") do echo(%%A
If blank lines, but no line begins with :
setlocal enableDelayedExpansion
for /f "delims=: tokens=1*" %%A in ('findstr /n "^" "yourFile.txt"') do echo(%%B
If blank lines, and some lines begin with :
setlocal enableDelayedExpansion
for /f "delims=" %%A in ('findstr /n "^" "yourFile.txt"') do (
set "ln=%%A"
echo(!ln:*:=!
)
So I take it you want the contents of a file to be expanded just like variables.
Here you go:
>echo %hello%>file.txt
>type file.txt
%hello%
>set hello=holi
>type file.txt
%hello%
>for /f %f in (file.txt) do #echo %f
%hello%
>for /f %f in (file.txt) do #call echo %f
holi
>
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
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
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)
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%"