1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

How do I give this command?

Discussion in 'Support' started by vefatica, Mar 16, 2012.

  1. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,888
    Likes Received:
    30
    Code:
    c:\users\vefatica\desktop> type folders.reg | grep Name | egrep -v "zedN|arsing" | cut -c9- | tr -d "\"" > v:\FolderNames.txt
    tr: error: Can not open file 'v:\FolderNames.txt'[/CODE/
     
    It's the quoting.  How do I correctly quote TR's second argument?  The TR command is supposed to be:
     
    [CODE] tr -d "\""
    I tried escaping (^) the literal quote with up to 8 escape characters!
     
  2. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,888
    Likes Received:
    30
    Note that the very same command without the redirection works correctly.

    Code:
    c:\users\vefatica\desktop> type folders.reg | grep Name | egrep -v "zedN|arsing"
     | cut -c9- | tr -d "\""
    Common Programs
    GameTasks
    (snip)
     
  3. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,888
    Likes Received:
    30
    Here it is very simply. Ths command works but I can't redirect its output.

    Code:
    v:\> echo foo | tr "o" "\""
    f""
    v:\> echo foo | tr "o" "\"" > foofee.txt
    tr: error: Can not open file '>'
    fee
     
  4. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,888
    Likes Received:
    30
    And in the second above, 'o' was magically turned into 'e'.
     
  5. samintz

    samintz Scott Mintz

    Joined:
    May 20, 2008
    Messages:
    1,188
    Likes Received:
    11
    Have you tried using command grouping?
     
  6. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,888
    Likes Received:
    30
    Do you mean like this (which elicits a "More?" prompt)?

    Code:
    v:\> (echo foo | tr "o" "\"") > foofee.txt
    More?
     
  7. samintz

    samintz Scott Mintz

    Joined:
    May 20, 2008
    Messages:
    1,188
    Likes Received:
    11
    I was thinking more along the lines of:
    Code:
    echo foo | (tr "o" "\"" > foofee.txt)
    
     
  8. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,888
    Likes Received:
    30
    That's an interesting one!

    Code:
    v:\> echo foo | ( tr "o" "\"" > foofee.txt)
    More? More? TCC: Unbalanced parentheses "( tr "o" "\"" > foofee.txt) & foo "
     
  9. samintz

    samintz Scott Mintz

    Joined:
    May 20, 2008
    Messages:
    1,188
    Likes Received:
    11
    Well. Isn't that special?

    What if you use an in-process pipe?
    Code:
    echo foo |! tr "o" "\"" > foofee.txt
    
     
  10. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,888
    Likes Received:
    30
    That's a good one too!

    Code:
    v:\> echo foo |! tr "o" "\"" > foofee.txt
    tr: error: Can not open file '>'
    f^^
     
  11. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,888
    Likes Received:
    30
    You don't need any UNIX-like goodies.

    Code:
    v:\> del foofee.txt
    Deleting V:\foofee.txt
        1 file deleted
    v:\> echo "foo" | findstr "\""
    "foo"
    v:\> echo "foo" | findstr "\"" > foofee.txt
    FINDSTR: Cannot open foofee.txt
    v:\> touch /c foofee.txt
    3/16/2012 21:26:21.605  V:\foofee.txt
    v:\> echo "foo" | findstr "\"" > foofee.txt
    v:\> type foofee.txt
    v:\> dir /k /m foof*
     3/16/2012  21:26               0  foofee.txt
     
  12. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,523
    Likes Received:
    4
    I tried it in CMD.EXE - exact same issue as in TCC. The escaped quotation mark caused redirection failure. But this worked in both TCC and CMD:

    echo foo | tr "o" "\" > foo.txt

    Tested in WinXP home SP3, TCC 13.04.54. My version of tr is (GNU textutils) 2.0 (from 1999).
     
  13. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,888
    Likes Received:
    30
    echo foo | tr "o" "\" > foo.txt

    That command is not well-formed. What's the last quote doing?
    I get the expected error with my TR.
    Code:
    v:\> echo foo | tr "o" "\" > foo.txt
    fatal error: Missing double quote
     
  14. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    9,809
    Likes Received:
    82
  15. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    9,809
    Likes Received:
    82
    I tried:

    echo "foo" | findstr "\^"" > foofee.txt

    and it seems to work. Where were you putting the escapes?
     
  16. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,888
    Likes Received:
    30
    If you look at foofee.txt, I suspect it will be empty. And if you run that command without the redirection I think you'll get no output.
     
  17. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,523
    Likes Received:
    4
    I knew the command which actually worked here is technically incorrect. OTOH your error message is missing the information - which program detected the error? Was it TCC, CMD, or tr?

    BTW, this the command:
    echo foo | tr "o" "\"" >foo.txt
    reported in CMD:

    tr: too many arguments
    Try `tr --help' for more information.
    The process tried to write to a nonexistent pipe.

    The same command in TCC reported the first two lines (with full path for tr), but not the third line. No empty file was created by either command processor.

    I suspect that both the CMD and TCC parsers get mixed up on "\"" - is the backslash your TCC escape character? It is not mine...

    I discovered that TCC escape sequences, such as %=q, do not work inside quoted strings - seems the quotation marks surrounding the string allow translation of the %= to my chosen escape character (which is ctrl-X as in 4DOS), but the second translation of the sequence [EscapeChar]q into a quotation mark does not take place.

    BTW, the same issues occur in
    tr "o" "\"" > foo.txt
    (which expects the word "foo" from the keyboard) without the left side of the pipe, the issue is not related to piping. It definitely is related to redirection.

    The simple command
    echo %@replace[o,%=q,foo] > foo.txt
    works, but add another o into the source string:
    echo %@replace[o,%=q,foorox] > foo.txt
    and it gets confused, and instead of redirection, displays
    f""r"x > foo.txt
     
  18. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,888
    Likes Received:
    30
    Isn't the question rather simple? I have a working command:

    Code:
    v:\> echo "foo" | findstr "\""
    "foo"
    And I cannot redirect its output:

    Code:
    v:\> echo "foo" | findstr "\"" > foofee.txt
    FINDSTR: Cannot open foofee.txt
     
  19. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,888
    Likes Received:
    30
    And what's going on when there are quotes missing at the end of a line?
    Code:
    v:\> cd "a b
     
    v:\a b> echo foo > "c d.txt"
    v:\a b> type "c d.txt
    foo
     
  20. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    9,809
    Likes Received:
    82
     
  21. Charles Dye

    Charles Dye Super Moderator
    Staff Member

    Joined:
    May 20, 2008
    Messages:
    3,288
    Likes Received:
    39
  22. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,888
    Likes Received:
    30
    That helps the versions of the commands that involve redirection:

    Code:
    v:\> echo "foo" | findstr ^"\^"^" > foofee.txt
    v:\> type foofee.txt
    "foo"
    v:\> type folders.reg | grep Name | egrep -v "zedN|arsing" | cut -c9- | tr -d ^"\^"^" > v:\FolderNames.txt
    v:\> head /n2 FolderNames.txt
    Common Programs
    GameTasks
    But remove the redirection and the commands fail:

    Code:
    v:\> echo "foo" | findstr ^"\^"^" (no output)
    v:\> type folders.reg | grep Name | egrep -v "zedN|arsing" | cut -c9- | tr -d ^"\^"^"
    fatal error: Missing double quote
     
  23. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,888
    Likes Received:
    30
    That's one of the dumbest mistakes a user can make. You coddle them and they'll learn to use bad syntax.

    I spend 10-15 minutes stringing together GREP, EGREP, CUT, TR (et al., add 5-10 minutes if SED is involved) constructing a command to extract data from a file or stdout. When I finally get it right, I add redirection and it fails. I hope you can understand why that bugs me.
     
  24. Avi Shmidman

    Joined:
    Feb 23, 2012
    Messages:
    238
    Likes Received:
    3
    After reading Rex's post about the final quote mark being added automatically, I decided to just leave off that last quote mark, and I found that it works:
    echo "foo" | findstr "\" > foofee.txt

    Here's why, I believe:
    1] As far as TCC is concerned, the findstr command contains an open-quote and a close-quote (because TCC's escape character is ^, not \), and therefore when TCC parses the line it figures that the findstr command ends before the >, and thus it sends findstr a parameter of: "\"
    2] As far as FINDSTR is concerned, the backslash *is* an escape character. Therefore, when TCC passes the "\" on to findstr, findstr reads this as: open quote plus literal quote. Fortunately, findstr is just as forgiving as TCC about leaving off the endquote, so it supplements the endquote by itself, and hence it successfully performs the search for a quote mark.
     
  25. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,888
    Likes Received:
    30
    If FINDSTR in written in "C", I suspect it's seeing only the bare quote ... C's argv mechanism discarding enclosing quotes, treating the \escaped one as literal, and being forgiving about the missing close-quote.

    Code:
    v:\> EchoArgs.exe "\""
    EchoArgs.exe
    "
     
  26. Avi Shmidman

    Joined:
    Feb 23, 2012
    Messages:
    238
    Likes Received:
    3
    Hi Vince,
    1] Yes, your explanation of the argv processing in C makes sense. In any case, the upshot is that findstr searches for a double quote, which is what you were attempting to do, no?
    2] Which implementations do you use for grep/egrep/sed under Windows?

     
  27. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,888
    Likes Received:
    30
    Hi, Avi. I usually use utilities from the (14 year-old) "Thompson Toolkit", because I'm used to them and have the printed manual right next to me. I also have the Gnu textutils.
     
  28. Avi Shmidman

    Joined:
    Feb 23, 2012
    Messages:
    238
    Likes Received:
    3
    Thanks for the info Vince. I'll check it out.
    By the way, taking the cue from you about the usefullness of echoargs here, I looked at some various permutations of quotemarks in arguments, and found that the system is quite forgiving:

    [C:\Windows\System32\WindowsPowerShell\v1.0\Modules\Apps]echoargs \"
    Arg 0 is <">
    [C:\Windows\System32\WindowsPowerShell\v1.0\Modules\Apps]echoargs \""
    Arg 0 is <">
    [C:\Windows\System32\WindowsPowerShell\v1.0\Modules\Apps]echoargs \"""
    Arg 0 is <">
    [C:\Windows\System32\WindowsPowerShell\v1.0\Modules\Apps]echoargs \""""
    Arg 0 is <"">

    In the first case, it takes the single quote mark and just uses it as the argument. In the second case, there's a quote mark plus an end quote. So it's fine with that, it just discards the end quote. Skipping to the fourth case, we see that two quotes also indicate a literal quotemark; so that case has two literal quotemarks, plus an end-quote that is discards.
    The third case is interesting, though. I would have thought that the two quotes at the end would be parsed as a literal quote, but apparently the quote at the end is first discarded as an end-quote, and then the remaining quote is also discarded forgivingly.

    The importance of all of this is that it means that when formulating strings of commands on the command line, it is generally possible to simply add an extra quote at the end as necessary in order to balance the number of quotes, such that the redirection operator will be parsed correctly.
     
  29. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,888
    Likes Received:
    30
    I'm afraid that's not true.

    Code:
    v:\> echo "foo" | findstr "\""
    "foo" (worked)
    v:\> echo "foo" | findstr "\""" > foofee.txt
    v:\> type foofee.txt
    (nothing, because as you pointed out, FINDSTR sees ""
    v:\> EchoArgs.exe "\"""
    EchoArgs.exe
    ""
     
  30. Avi Shmidman

    Joined:
    Feb 23, 2012
    Messages:
    238
    Likes Received:
    3
    OK, Vince, here's a way to do it, using the ^ escape character for the first quotemark:

    (1) echo "foo" | findstr ^"\"" > foofee.txt

    This works both with redirection and without. Essentially, what we've done, I think, is that we've told TCC not to count that first quotemark when it looks to see whether the quotemarks are balanced or not, and therefore it ends up counting two quotemarks - a balanced number - and the line is thus properly split before the redirection operator.

    Note that if we put the carrot in the middle, it doesn't work:
    (2) echo "foo" | findstr "\^"" > foofee.txt
    This is probably because the carrot is now appearing after the initial quote, and thus considered part of the literal, and not an escape.

    The puzzling thing, though, is what happens when we put it before the last quote mark:
    (3) echo "foo" | findstr "\"^" > foofee.txt
    Here the command works with the redirection but not without the redirection, as in Charles' example above. I am at a loss to explain this.
     

Share This Page