JPand Katie
JPand Katie

Reputation: 23

For /F loop throwing "syntax of the command is incorrect"

Having issues for days now trying to figure this out, and hoping the community here can assist. Running the following command in a batch generates "the syntax of the command is incorrect", and I thinks its probably backquote placement, but I can't seem to figure out the right combo of quotes. Assistance would be greatly appreciated :)

FOR /F "USEBACKQ TOKENS=* DELIMS=" %%d IN (`"C:\PROGRAM FILES\7-Zip\7z.exe" l C:\TEST\FHNVPROV.XXX.0704.zip -slt ^| FINDSTR /s /i "\FHNVPROV\>"`) DO (SET "NAME=%%d")

I'm trying to use the For loop to launch 7-zip and read the contents of a .zip file (which only contains a text file of the same name "FHNVPROV.XXX.0704.txt"), find that .txt file name and output it to a variable.

Both commands work by themselves when run from a command line. I can even get them run piped correctly from a command line. And, depending on my experimentation with quote placement and usebackq, I've been able to get portions of the above to work, which is why I felt like that was my key here. Thanks all! :)

Upvotes: 0

Views: 833

Answers (1)

aschipfl
aschipfl

Reputation: 34909

Before I tell you what is wrong here, I assume you intended to use the regular expression \<FHNVPROV\> (there is the < missing in your question; I also put the ZIP file path in "" here):

FOR /F "USEBACKQ TOKENS=* DELIMS=" %%d IN (`"C:\PROGRAM FILES\7-Zip\7z.exe" l "C:\TEST\FHNVPROV.XXX.0704.zip" -slt ^| FINDSTR /s /i "\<FHNVPROV\>"`) DO (SET "NAME=%%d")

The problem is that the expression within the set of the for /F loop (that is the parsed part within parentheses) looks enclosed within "" to the for /F command (even though it is already enclosed within ``), because the first and last characters in between the backticks are " both. The for /F command seems to remove the backticks and also the first and the last quotation marks and executes the remainder, which is: C:\PROGRAM FILES\7-Zip\7z.exe" l "C:\TEST\FHNVPROV.XXX.0704.zip" -slt ^| FINDSTR /s /i "\<FHNVPROV\>. This is of course an invalid command line and therefore a syntax error arises.

To work around this issue, you have got the following options:

  1. to avoid the first or the last character to be a quotation mark; in the following example I used the short name of the directory C:\Program Files (type dir /X "C:\Program Files*" in command prompt to find out; I used C:\PROGRA~1 here), so it does not contain white-spaces and hence no "" are required any more:

     FOR /F "USEBACKQ TOKENS=* DELIMS=" %%d IN (`C:\PROGRA~1\7-Zip\7z.exe l "C:\TEST\FHNVPROV.XXX.0704.zip" -slt ^| FINDSTR /s /i "\<FHNVPROV\>"`) DO (SET "NAME=%%d")
    
  2. to place another pair of quotation marks around the entire expression; the for /F command removes the `` and the outermost "", so the remainder is a valid command line; however, the command interpreter will now detect the < and > characters in the regular expression to be outside of a quoted string, so you need to escape them; the | however is seen as part of a quoted string, so no escaping is necessary, although it would not harm; to understand that, you need to read the line from left to right character by character, and to imagine a sort of "quoted" flag, which is toggled as soon as you encounter a ", and which disables recognition of special characters when set (see also this post):

     FOR /F "USEBACKQ TOKENS=* DELIMS=" %%d IN (`""C:\Program Files\7-Zip\7z.exe" l "C:\TEST\FHNVPROV.XXX.0704.zip" -slt | FINDSTR /s /i "\^<FHNVPROV\^>""`) DO (SET "NAME=%%d")
    

EDIT - You can avoid restructuring the command by escaping the outer quotes instead:

FOR /F "USEBACKQ TOKENS=* DELIMS=" %%d IN (`^""C:\Program Files\7-Zip\7z.exe" l "C:\TEST\FHNVPROV.XXX.0704.zip" -slt ^| FINDSTR /s /i "\<FHNVPROV\>"^"`) DO (SET "NAME=%%d")

Upvotes: 4

Related Questions