Is there any way to get for /f loop (or anything else) to read a specific line?
Here is the code I have so far, it reads first word of every line.
@echo
Since you haven't fully defined what you mean by "a specific location", I'll make some (reasonable, in my opinion) assumptions, though the method I present is equally valid no matter what your definition turns out to be.
You can get arbitrary lines and arbitrary words on that line by using a line counter variable in conjunction with tokens
.
Let's assume your text file name can be found as the second argument on the fourth line of the infile.txt
file. You can get that with something like:
@setlocal enableextensions enabledelayedexpansion
@echo off
set /a "line = 0"
for /f "tokens=2 delims= " %%a in (infile.txt) do (
set /a "line = line + 1"
if !line!==4 set thing=%%a
)
endlocal & set thing=%thing%
echo %thing%
This actually uses a few "tricks" which warrant further explanation:
line
counter to ensure you only grab what you want from a specific line, though you could change the test !line!==4
into anything you need such as a line beginning with #
, the fifth line containing the string xyzzy
and so on.setlocal/endlocal
to effectively give you a scope from which variables cannot leak. This is good programming practice even for a language often not normally associated with such things :-)endlocal & set
to bypass that scope so that thing
is the only thing that does actually leak (as it should).!..!
variables to ensure they're correct within the for
loop. Without this, the %..%
will always be expand to the value they were set to when the for
loop started.Those last two bullet points are actually related. %..%
variables are expanded when the command is read rather than when it is executed.
For a for
loop, the command is the entire thing from the for
to the final )
. That means, if you use %line%
within the loop, that will be evaluated before the loop starts running, which will result in it always being 0
(the variable itself may change but the expansion of it has already happened). However, !line!
will be evaluated each time it is encountered within the loop so will have the correct value.
Similarly, while endlocal
would normally clear out all variables created after the setlocal
, the command:
endlocal & set thing=%thing%
is a single command in the context of expansion. The %thing%
is expanded before endlocal
is run, meaning it effectively becomes:
endlocal & set thing=whatever_thing_was_set_to_before_endlocal
That's why the use of setlocal
and endlocal & set
is a very useful way to limit variables "escaping" from a scope. And, yes, you can chain multiple & set
stanzas to allow more variables to escape the scope.