#1 25 Oct 2012 09:42

carlos
Member
From: Chile
Registered: 04 Nov 2008
Posts: 212
Website

For /f documentation

Hello.
In the two pages of for /f documentation, for_cmd.html and for_f.html when mentions the info about the 61 tokens and show the caret, the ascii symbol for copy paste is other. The ascii code for caret is 0x5e and the two pages use in the sequence the ascii code 0x88

Also, the two pages don't mentions the undocumented option: useback as a abbreviation of usebackq

Too, when say: in theory "eol=" should turn this feature off, but in practice this fails.
I would like add that when you specify the eol option within quotes the next character is read and used. So if you use this options "eol=" the eol character would be the " (quote) or if you use this options "eol= delims=" the eol character assumed is the space. Then, if you like disable the eol character you would be not enclose the options in quotes and escape special characters (space equal colon) writing eol= to the end (important!) without specifing any character, like this (read all tokens, dont use delimiter and dont use eol):

For /f tokens^=*^ delims^=^ eol^= %%a in (file.txt) do echo.%%a

instead of:

For /f "tokens=* delims= eol=" %%a in (file.txt) do echo.%%a

Anyways, when For /f open a file for read, read until the end or found the ascii 0.
Because this, if you have a file.txt with this lines:

;semicolon
"quote
 space
%percent
=equal
NUL_0
^caret

where NUL_0 is in binary these hex ascii: 00 5f 30
and you open the file with for /f you read all the lines until the line =equal

Because the hex 0 is a string terminator and in this line is used at the begin, you can't save the line NUL_0 in a variable and neither print. For catch it line you need replace the hex 0 for a 0xd 0xa using the find command, find /v "" file.txt

In conclusion, the secure way for read all the lines with text of a file is the next way:

For /f skip^=2^ tokens^=*^ delims^=^ eol^= %%a in ('Find /v "" file.txt') do echo.%%a

But, because generally the text files don't have hex 0 poisoning characters, is enough with this:

For /f tokens^=*^ delims^=^ eol^= %%a in (file.txt) do echo.%%a

Last edited by carlos (25 Oct 2012 09:51)

Offline

#2 25 Oct 2012 14:07

dbenham
Member
From: U.S. east coast
Registered: 15 Apr 2012
Posts: 99

Re: For /f documentation

Wow, very cool cool

The only way I knew to effectively disable both EOL and DELIMS was to set EOL to a linefeed character. This works because FOR /F delimits lines at linefeed, so it can never read one. But the syntax is ugly: http://www.dostips.com/forum/viewtopic.php?p=10729

for /f eol^=^

^ delims^= %%a in ...

or

set LF=^


for /f eol^=^%LF%%LF%^ delims^= %%a in ...

But I like your syntax much better. I think all the batch file "experts" got so used to always putting DELIMS at the end so that we could use a space that we never thought to put EOL at the end instead.

Note that your use of TOKENS=* is not needed if DELIMS is disabled. I see many people add that unnecessary bit. All that is needed is:

for /f delims^=^ eol^= %%a in ...

And to disable EOL when DELIMS is not disabled, then all you need to do is set EOL to one of the delimiter characters. (noted in the earlier link in my post)

If using default DELIMS=space and tab

for /f "eol= " %%a in ...

If explicitly defining DELIMS

for /f "eol=, delims=,;" %%a in ...

------------------

Also good to know about the NUL character issue - thanks.

Last edited by dbenham (25 Oct 2012 14:57)

Offline

#3 25 Oct 2012 18:58

carlos
Member
From: Chile
Registered: 04 Nov 2008
Posts: 212
Website

Re: For /f documentation

Thanks for the note. You are right, if you disable delims and eol is unnecessary use tokens=*

But, be careful if you don't disable delims, always you do a left trim of all initial characters.

Test the next code:

::delims is # eol disabled
For /f delims^=#^ eol^= %%a in ("###trim ###") do echo.%%a

::delims is # eol disabled tokens=*
For /f tokens^=*^ delims^=#^ eol^= %%a in ("###trim ###") do echo.%%a

::delims is # eol is #
For /f "tokens=* delims=# eol=#" %%a in ("###trim ###") do echo.%%a

::delims is # eol is disabled
For /f delims^=#^ eol^= %%a in ("###trim ###") do echo.%%a

::delims is disabled # eol is disabled tokens=* is unnecesary
For /f delims^=^ eol^= %%a in ("###trim ###") do echo.%%a

::delims is disabled # eol is disabled tokens=* is redundant
For /f tokens^=*^ delims^=^ eol^= %%a in ("###trim ###") do echo.%%a

Last edited by carlos (25 Oct 2012 18:58)

Offline

#4 25 Oct 2012 20:34

Simon Sheppard
Super Administrator
Registered: 27 Aug 2005
Posts: 736
Website

Re: For /f documentation

Great sleuthing Carlos!, I've updated both those pages now.

Offline

Board footer

Powered by FluxBB