How do I give this command?

May 20, 2008
9,867
69
Syracuse, NY, USA
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!
 
May 20, 2008
9,867
69
Syracuse, NY, USA
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!
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)
 
May 20, 2008
9,867
69
Syracuse, NY, USA
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
 
May 20, 2008
9,867
69
Syracuse, NY, USA
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
And in the second above, 'o' was magically turned into 'e'.
 
May 20, 2008
9,867
69
Syracuse, NY, USA
I was thinking more along the lines of:
Code:
echo foo | (tr "o" "\"" > foofee.txt)
That's an interesting one!

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

samintz

Scott Mintz
May 20, 2008
1,364
12
Solon, OH, USA
Well. Isn't that special?

What if you use an in-process pipe?
Code:
echo foo |! tr "o" "\"" > foofee.txt
 
May 20, 2008
9,867
69
Syracuse, NY, USA
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
 
May 20, 2008
3,515
3
Elkridge, MD, USA
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).
 
May 20, 2008
9,867
69
Syracuse, NY, USA
echo foo | tr "o" "\" > foo.txt

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
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
 
May 20, 2008
9,867
69
Syracuse, NY, USA
I tried:

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

and it seems to work. Where were you putting the escapes?
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.
 
May 20, 2008
3,515
3
Elkridge, MD, USA
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
 
May 20, 2008
9,867
69
Syracuse, NY, USA
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
 
May 20, 2008
9,867
69
Syracuse, NY, USA
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
 
May 20, 2008
9,867
69
Syracuse, NY, USA
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
 
May 20, 2008
9,867
69
Syracuse, NY, USA
TCC is adding a closing double quote when one is missing. (This was done about 15 years ago, because users were complaining about error messages when they forgot to close quotes.)
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.
 
Feb 23, 2012
240
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.
 
May 20, 2008
9,867
69
Syracuse, NY, USA
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.
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
"
 
Feb 23, 2012
240
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?

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.
 
Feb 23, 2012
240
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.
 
May 20, 2008
9,867
69
Syracuse, NY, USA
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.
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
""
 
Feb 23, 2012
240
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.