86} How to put each line of a text file into an environment variable?
Assume the following LFN-type test file: "My test file.txt"
line 1
line 2
line 3
5
06
line 7 Line "4" is blank, "5" and "6" are short!
line 8
line 9 ends it
Note the use of the delayed expansion method
@echo off & setlocal enableextensions enabledelayedexpansion
set myfile_=C:\_D\TEST\My test file.txt
for %%f in ("%temp%\tmp$$$.cmd") do if exist %%f del %%f
::
:: Do it
set lineNro_=
for /f "tokens=* delims=" %%r in ('type "%myfile_%"') do (
set /a lineNro_+=1
echo @set line!lineNro_!_=%%r>>"%temp%\tmp$$$.cmd"
)
:: Call the prepared auxiliary script and clean up
for %%c in (call del) do %%c "%temp%\tmp$$$.cmd"
::
:: Display the outcome
for /L %%v in (1,1,%lineNro_%) do echo line%%v_=!line%%v_!
endlocal & goto :EOF
The output will be
C:\_D\TEST>cmdfaq
line1_=line 1
line2_=line 2
line3_=line 3
line4_=5
line5_=06
line6_=line 7 Line "4" is blank, "5" and "6" are short
line7_=line 8
line8_=line 9 ends it
Observe that the empty line (the true fifth line) was skipped, and
that the exclamation mark
! does not
appear because of the enabled delayedexpansion. Also note that it is
advisable that the text file not contain the special script characters
&()[]{}^=;!'+,`~
Actually, employing the intermediate script file
%temp%\tmp$$$.cmd is not necessary:
@echo off & setlocal enableextensions enabledelayedexpansion
set myfile_=C:\_D\TEST\My test file.txt
::
:: Do it
set lineNro_=
for /f "tokens=* delims=" %%r in ('type "%myfile_%"') do (
set /a lineNro_+=1
set line!lineNro_!_=%%r)
::
:: Display the outcome and clean up
for /L %%v in (1,1,%lineNro_%) do echo line%%v_=!line%%v_!
endlocal & goto :EOF
How about without the delayed expansion? First consider
@echo off & setlocal enableextensions
disabledelayedexpansion
::
:: Make a test file
set myfile_=C:\_D\TEST\My test file2.txt
for %%f in ("%myfile_%") do if exist %%f del %%f
for %%f in (first! second third fourth) do (
echo This is the %%f line>>"%myfile_%")
echo.>>"%myfile_%"
for %%f in (sixth seventh eight ninth tenth eleventh) do (
echo This is the %%f line>>"%myfile_%")
::
for %%f in ("%temp%\tmp$$$.cmd") do if exist %%f del %%f
::
:: Do it
set lineNro_=
for /f "tokens=* delims=" %%r in ('type "%myfile_%"') do (
call :ProcessOneLine %%r)
call "%temp%\tmp$$$.cmd"
::
:: Display the outcome
for /L %%v in (1,1,%lineNro_%) do (
call echo line%%v_=%%line%%v_%%
)
::
:: Clean up
for %%f in ("%temp%\tmp$$$.cmd" "%myfile_%") do (
if exist %%f del %%f)
endlocal & goto :EOF
::
:ProcessOneLine
set /a lineNro_+=1
set row=%*
echo @set line%lineNro_%_=%row%>>"%temp%\tmp$$$.cmd"
goto :EOF
The output will be
C:\_D\TEST>cmdfaq
line1_=This is the first! line
line2_=This is the second line
line3_=This is the third line
line4_=This is the fourth line
line5_=This is the sixth line
line6_=This is the seventh line
line7_=This is the eight line
line8_=This is the ninth line
line9_=This is the tenth line
line10_=This is the eleventh line
The empty line is dropped. But in all the results
are as expected, including the exlamation mark on the first line.
However, let's alter the test file a bit so that the contents of the
test file will be
This is line 1!
This is line 2
This is line 3
This is line 4
This is line 6
This is line 7
This is line 8
This is line 9
This is line 10
This is line 11
@echo off & setlocal enableextensions disabledelayedexpansion
::
set myfile_=C:\_D\TEST\My test file2.txt
for %%f in ("%myfile_%") do if exist %%f del %%f
for %%f in (1! 2 3 4) do (
echo This is line %%f>>"%myfile_%")
echo.>>"%myfile_%"
for %%f in (6 7 8 9 10 11) do (
echo This is line %%f>>"%myfile_%")
::
for %%f in ("%temp%\tmp$$$.cmd") do if exist %%f del %%f
::
:: Do it
set lineNro_=
for /f "tokens=* delims=" %%r in ('type "%myfile_%"') do (
call :ProcessOneLine %%r)
call "%temp%\tmp$$$.cmd"
::
:: Display the outcome
for /L %%v in (1,1,%lineNro_%) do (
call echo line%%v_=%%line%%v_%%
)
::
:: Clean up
for %%f in ("%temp%\tmp$$$.cmd" "%myfile_%") do (
if exist %%f del %%f)
endlocal & goto :EOF
::
:ProcessOneLine
set /a lineNro_+=1
set row=%*
echo @set line%lineNro_%_=%row%>>"%temp%\tmp$$$.cmd"
goto :EOF
As you'll observe, the output "is all over the place"
@set line2_=This is line
@set line3_=This is line
@set line4_=This is line
@set line5_=This is line
@set line6_=This is line
@set line7_=This is line
@set line8_=This is line
line1_=This is line 1!
line2_=
line3_=
line4_=
line5_=
line6_=
line7_=
line8_=
line9_=This is line 10
line10_=This is line 11
This
is a conundrum, but probably has to do with the trailing line
number (when a single digit) in the text file being taken as a file
handle. When I posed this situation to the regulars in
alt.msdos.batch.nt
(as expected) workarounds were quickly found. Replace
echo @set line%lineNro_%_=%row%>>"%temp%\tmp$$$.cmd"
with
(echo @set line%lineNro_%_=%row%)>>"%temp%\tmp$$$.cmd"
or with
>>"%temp%\tmp$$$.cmd" echo @set line%lineNro_%_=%row%
Also see
item #82.
Let's return to the original task with a twist.
Assuming that the file "My test file.txt" contains a single line of
the form
20080621
How to generate a one line command in the CLI (i.e. not a batch file!)
to echo (just) the year?
for /f %a in ('type "My test file.txt"') do @set IDate=%a&@call echo %IDate:~0,4%