Windows Batch file to echo a specific line number

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
  )
)

Leave a Comment