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"').
- 'findstr /n .* "PATH\FILENAME"' reads the file and adds a line number ('/n') to every line ('.*' is a regular expression matching "0 or more" of any character). Since every line will now have a line number at the beginning (even the empty ones), no lines will be skipped by the for loop.
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.
- 'tokens=1*' sets the first token (stored in %%a) to everything before the delimiter, and the second token (stored in %%b) to everything after it.
- 'delims=:' sets ":" as the delimiter character used to break up the string.
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
)
)