72} Is it possible to use quotes as delims in for loops?
The default delimiter set of delims in a FOR /F loop is space and
tab. That can be replaced by defining delims=xyz as the delimiter
set. Assume that we have a data file "myfile.txt"
Line,1,Part,1
Line,2,Part,1
Line,3,Part,1
Line,4,Part,1
Line,6,Part,2
Line,7,Part,2
Line,8,Part,2
Line,9,Part,2
Then
@echo off & setlocal enableextensions
set myfile_=myfile.txt
for /f "tokens=2,4 delims=," %%a in ('type "%myfile_%"') do (
echo %%a %%b)
endlocal & goto :EOF
will result in
1 1
2 1
3 1
4 1
6 2
7 2
8 2
9 2
Note that the method omits the empty line.
Now, what if instead we had for whatever strange reason in myfile.txt
Line"1"Part"1
Line"2"Part"1
Line"3"Part"1
Line"4"Part"1
Line"6"Part"2
Line"7"Part"2
Line"8"Part"2
Line"9"Part"2
Then we would have to take the following steps, first replacing the
quotes (") e.g. with commas (,)
@echo off & setlocal enableextensions enabledelayedexpansion
set myfile_=myfile.txt
::
:: Make an auxiliary temporary folder
if not exist "c:\mytemp" mkdir "c:\mytemp"
::
:: Make sure that the auxiliary file will be build up from scratch
del "c:\mytemp\tmp$$$.txt" > nul 2>&1
::
:: Echo each line substituting quotes with commas
for /f "tokens=*" %%c in ('type "%myfile_%"') do (
set lineContents=%%c
echo !lineContents:"=,!
)>>"c:\mytemp\tmp$$$.txt"
::
:: Echo the second and the fourth token on each line
for /f "tokens=2,4 delims=," %%a in ('type "c:\mytemp\tmp$$$.txt"') do (
echo %%a %%b)
::
:: Clean up
for %%f in ("c:\mytemp\tmp$$$.txt") do if exist %%f del %%f
rmdir "c:\mytemp"
endlocal & goto :EOF
This will, again, result in
1 1
2 1
3 1
4 1
6 2
7 2
8 2
9 2
Alternatively
@echo off & setlocal enableextensions
set myfile_=c:\_m\Myfile.txt
for /f "tokens=2,4 delims=," %%a in ('
type "%myfile_%"^|
sed -e "s/\x22/,/g"') do (
echo %%a %%b)
endlocal & goto :EOF
Stepping outside FOR loops, one could use
@echo off & setlocal enableextensions
set myfile_=c:\_m\myfile.txt
<"%myfile_%"
gawk -F" '{printf "%%s %%s\n",$2,$4}'
endlocal & goto :EOF
The output is (now including the empty line)
1 1
2 1
3 1
4 1
6 2
7 2
8 2
9 2
The problem about using quotes as delims in for loops can also be
solved with a Visual Basic Script (
VBScript)
aided command line script. Again, consider the data file,
this time located at C:\_D\TEST\My test file.txt
Line,1,Part,1
Line,2,Part,1
Line,3,Part,1
Line,4,Part,1
Line,6,Part,2
Line,7,Part,2
Line,8,Part,2
Line,9,Part,2
@echo off setlocal enableextensions
set myfile_=C:\_D\TEST\My test file.txt
set tempfile_=%temp%\tmp.txt
::
:: Build a Visual Basic Script
set skip=
set vbs_=%temp%\tmp$$$.vbs
>"%vbs_%" findstr "'%skip%VBS" "%~f0"
::
cscript //nologo "%vbs_%" < "%myfile_%" > "%tempfile_%"
::
for /f "tokens=2,4 delims=," %%a in ('
type "%tempfile_%"') do echo %%a--%%b
::
:: Clean up
for %%f in ("%vbs_%" "%tempfile_%") do if exist %%f del %%f
endlocal goto :EOF
'
'............................................
'The Visual Basic Script
'
Do While Not WScript.StdIn.AtEndOfStream 'VBS
str = WScript.StdIn.ReadLine 'VBS
str = Replace (str, Chr(34),",") 'VBS
WScript.StdOut.WriteLine str 'VBS
Loop 'VBS
The output is (note skipping the empty line)
C:\_D\TEST>cmdfaq
1--1
2--1
3--1
4--1
6--2
7--2
8--2
9--2
Note that the delimiters cannot be strings, only characters, even
though there can be several of them defined in delims=