0

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! :)

aschipfl
  • 28,946
  • 10
  • 45
  • 77

1 Answers1

4

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")
Community
  • 1
  • 1
aschipfl
  • 28,946
  • 10
  • 45
  • 77
  • I tried to suggest the escaped quotes in a comment, but the backslashes messed up the in-line code syntax. So I decided to edit your answer instead. – dbenham Mar 11 '16 at 01:55
  • Thanks a lot, @dbenham! If you had posted your own answer, I would definitely have upvoted it as this is the most convenient solution... – aschipfl Mar 11 '16 at 01:59
  • Thanks to everyone for the assistance and the awesome explanations! Learned a thing or two today :) Greatly appreciated! – JPand Katie Mar 14 '16 at 14:21
  • You're welcome! please consider to accept the answer in case it helped you and fully addressed the issue of your question... – aschipfl Mar 14 '16 at 14:26