<http://www.netikka.net/tsneti/info/tscmd086.htm>
Copyright © 2003-2010 by Prof. Timo Salmi  
Last modified Sat 1-May-2010 10:16:44

 
Assorted NT/2000/XP/.. CMD.EXE Script Tricks
From the html version of the tscmd.zip 1cmdfaq.txt file
To the Description and the Index
 

This page is edited from the 1cmdfaq.txt faq-file contained in my tscmd.zip command line interface (CLI) collection. That zipped file has much additional material, including a number of detached .cmd script files. It is recommended that you also get the zipped version as a companion.

Please see "The Description and the Index page" for the conditions of usage and other such information.



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%

References/Comments: (If a Google message link fails try the links within the brackets.)
  Google Groups 24.06.2008 11:11 [M]
  Google Groups 24.06.2008 13:19 [M]
  Google Groups 24.06.2008 19:01 [M]
  Google Groups 21.06.2008 15:16 [M]
  Google Groups May 1 2010, 6:36 am [M]