So for the second part of my current dilemma, I have a list of folders in c:\file_list.txt
. I need to be able to extract them (well, echo them with some mods) based on the line number because this batch script is being called by an iterative macro process. I'm passing the line number as a parameter.
@echo off
setlocal enabledelayedexpansion
set /a counter=0
set /a %%a = ""
for /f "usebackq delims=" %%a in (c:\file_list.txt) do (
if "!counter!"=="%1" goto :printme & set /a counter+=1
)
:printme
echo %%a
which gives me an output of %a
. Doh! So, I've tried echoing !a!
(result: ECHO is off.
); I've tried echoing %a
(result: a)
I figured the easy thing to do would be to modify the head.bat
code found here:
Windows batch command(s) to read first line from text file
except rather than echoing every line - I'd just echo the last line found. Not as simple as one might think. I've noticed that my counter is staying at zero for some reason; I'm wondering if the set /a counter+=1
is doing what I think it's doing.
I know this is an old question, but here is some additional info for anyone with a similar issue...
Lee, your reasoning on why "%%a" isn't working outside the for loop is correct. The %a-z and %A-Z variables (%%a-z inside a batch file) are a construct of the for loop, and do not exist outside of it.
I would like to recommend an alternative solution to this problem that matches the correct line numbers (no empty lines skipped) and does not require delayed expansion, counters, or a goto statement. Take a look at the following code:
@echo off
for /f "tokens=1* delims=:" %%a in ('findstr /n .* "c:\file_list.txt"') do if "%%a"=="%1" set line=%%b
echo.%line%
Here is what led me to the above changes. Let's say you had the following file contents:
Some text on line 1
Blah blah blah
More text
The first thing I did was change (c:\file_list.txt).to ('findstr /n .* "c:\file_list.txt"').
Each line will now look like this inside the for loop:
1:Some text on line 1
2:Blah blah blah
3:More text
Next, we use "tokens=1* delims=:" to break up the line number and the content.
Now as we loop through the file, %%a will return the current line number and %%b will return the content of that line.
All that's left is to compare the %1 parameter to %%a (instead of a counter variable) and use %%b to store the current line content: if "%%a" =="%1" set line=%%b.
An added bonus is that 'enabledelayedexpansion' is no longer necessary, since the above code eliminates reading a counter variable in the middle of a for loop.
Edit: changed 'echo %line%' to 'echo.%line%'. This will correctly display blank lines now, instead of "ECHO is off.". Changed 'type c:\file_list.txt ^| findstr /n .*' to 'findstr /n .* "c:\file_list.txt"', since the findstr command can already read files directly.
Jeb, I think I've solved all the special character issues. Give this a shot:
for /f "tokens=*" %%a in ('findstr /n .* "c:\file_list.txt"') do (
set "FullLine=%%a"
for /f "tokens=1* delims=:" %%b in ("%%a") do (
setlocal enabledelayedexpansion
set "LineData=!FullLine:*:=!"
if "%%b" equ "%1" echo(!LineData!
endlocal
)
)
Bah, it ate my formatting.
@echo off
setlocal enabledelayedexpansion
set /a counter=0
set %%a = ""
for /f "usebackq delims=" %%a in (c:\file_list.txt) do (if "!counter!"=="%1" goto :printme & set /a counter+=1)
:printme
echo %%a%
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With