How do I get Cygwin's grep to work properly in a regular cmd.exe?
> grep -o 'ProductVersion\".*\".*\"' foo.txt | grep -o '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+'
foo.txt:ProductVersion" Value="59.59.140.59"
grep: |: No such file or directory
grep: grep: No such file or directory
grep: [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+: No such file or directory
and
> grep -o 'ProductVersion\".*\".*\"' foo.txt >> blah.txt
foo.txt:ProductVersion" Value="59.59.140.59"
grep: >>: No such file or directory
grep: blah.txt: No such file or directory
Will gladly accept someone else's answer, but modifying my command to not use escaped quotes solved my issue. Thanks, @barlop.
In my particular search, I was able to change
grep -o 'ProductVersion\".*\".*\"' foo.txt >> blah.txt
to
grep -o 'ProductVersion.*Value.*' foo.txt | grep -v Name >> blah.txt
I would call this more of a workaround.
Best Answer
For Cygwin's grep
A workaround, is that you can specify the ASCII value in Bash.
"
is 22 in hex.Two points: You have to remove the single quotes from around the first part, so that
$'\x22'
is interpreted as special, not as literal.And for the second part of the expression you can't just use
-o
, it has to be-oE
.Because
+
is part ofERE
, and without-E
, it's justBRE
. It thinks+
is literal.Proof
+
is literal there.. 55.55.55.55 won't match but this will:So here's the line you had but adjusted..
Using Bash's feature of expanding ASCII codes, instead of using quotes. Removing quotes from around the first part, and adding
-E
to second part:ADDED
If you replace
[0-9]+
with[0-9][0-9]*
(which is the same), then you can use grep without the-E
.You can use
grep -P
and then you can use\d
for[0-9]
, but you have to use quotes around the second part. Or\\d
.In fact, here is a great solution that totally solves your original problem.. You only need a quote around the problematic bit. (By the way, I could make the regular expression in the second half more efficient using the repetition operator, but that's not relevant to the issue we've had with quotes which I'm focussing on).
This works. Dropping the single quotes from the first bit, and using
\"
to make them literal quotes. This gets round the bug of the double quotes needing to be single quoted. (Weird bug if Windows NT'sfindstr
has something like it, though not with single quotes no doubt.)grep -P
in the second part, allows us to use\d
. We could put quotes around the regular expression in the second half. Or, we can just put quotes around the'\d\
or, we can do as I have done and use\\d.
(\d
alone -unescaped and unquoted, won't match because it gets interpreted by Bash and reduced tod
whengrep
gets it.)Now that we've dealt with the quotes issue, I'll make it more efficient with the repetition operator. The regular expression of
3{4}
means3333
. The regular expression of(fg){4}
would meanfgfgfgfg
.