Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I can process a file-and-command,file-and-string or few files with FOR /F but no other combinations.Why?

Tags:

batch-file

cmd

Here's my code:

@echo off

echo ->minus
echo _>underscore
rem if this file  is used it tries to execute a command
echo not-at-all>'notacomand'

echo processing two files at once
for /f "delims=" %%# in (minus underscore ) do echo %%#
echo processing file and command
for /f "delims=" %%# in (minus '"echo ++"') do echo %%#
echo processing files and string
for /f "delims=" %%# in (minus underscore  "zzz") do echo %%#

rem searches for file "zzz" minus
rem for /f "delims=" %%# in ("zzz" minus) do echo %%#

rem searches for file  zzz" minus 
rem for /f "delims=" %%# in ("zzz" minus) do echo %%#

echo the command at the end is not processed
for /f "delims=" %%# in (minus "zzz" 'echo ---') do echo %%#

rem searches for file 'echo 
rem for /f "delims=" %%# in (minus  'echo ---' "zzz") do echo %%#

Tested on Windows 8.1 and Windows XP. ]:-).

I've tested very few combinations but my conclusions so far are:

  1. You can process as many files as you want at once.Wild cards are not accepted.For files with spaces useback should be used.
  2. You can process as many files as you want at once puls ONE command (but with additional double quotes) or string.Everything after the string or command will be ignored except syntax errors.

Have no idea why (most probably without the cmd code answer is impossible).Also have no idea if this can be useful or is known behavior , but definitely is curious.

like image 356
npocmaka Avatar asked Feb 17 '15 16:02

npocmaka


1 Answers

I'm pretty sure that you've run into a case of ambiguous documentation and a bug or two.

I believe what the documentation is trying to convey is that /f has three mutually exclusive choices: fileset, string, command output. One paragraph in the help begins with "You can also use the FOR /F parsing logic on an immediate string". I think "an" really means "one". Similarly the next paragraph says, "...output of a command...". Again I think "a" means one. My reasoning for mutually exclusive is that is how it is implemented more or less.

One of the bugs I'm claiming is that a single string works as a string if it's at the end of a fileset. The other might be the odd parsing of the quote characters that's been noted.

I think the high level parsing algorithm is something like: 1) look for open parenthesis, 2) if first non blank is quote character use appropriate handler for either string or command cases. 3) if first character is not quote or usebackq is specified and first character is double quote, then do fileset case 4) if previous token was a file specification then keep parsing, but if previous token was not a file specification then stop parsing

4) would explain the behavior of a single string at the end of a file set

String parsing algorithm seems to be: 1) look for beginning quote as first quote after open paren, 2) look for end quote as last quote before close paren, 3) everything in between is the string (or command) 4) the quotes don't even have to be balanced. The following all behave consistently with this explanation:

rem space is delimiter
for /f "tokens=1,2*" %i in ( "zzz" "yyy" ) do echo i %i j %j k %k
rem unbalanced quotes
for /f "tokens=1,2* delims=" %i in ( 'echo zzz' yyy' ) do echo i %i j %j k %k
rem apostrophe is delimiter
for /f "tokens=1,2* usebackq delims='" %i in ( 'zzz' 'yyy' ) do echo i %i j %j k %k
like image 71
Χpẘ Avatar answered Oct 12 '22 14:10

Χpẘ