0

I have GnuWin installed on a Windows 7 Enterprise SP1 x64 machine. I am trying to use grep 2.5.3 to match lines containing the word "true". The following is my working use-case:

(echo true& echo true2) | grep 'true'

The above matches both lines. Now I want to exclude the second line using the end-of-line anchor $ (dollar sign). I have tried the following variants, none of which match either line:

(echo true& echo true2) | grep 'true$'
(echo true& echo true2) | grep 'true\$'
(echo true& echo true2) | grep 'true\\$'
(echo true& echo true2) | grep 'true\\\$'
(echo true& echo true2) | grep 'true\\\\$'
(echo true& echo true2) | grep 'true\\\\\$'
(echo true& echo true2) | grep 'true\\\\\\$'
(echo true& echo true2) | grep 'true^$'
(echo true& echo true2) | grep 'true^^$'
(echo true& echo true2) | grep 'true^^^$'
(echo true& echo true2) | grep 'true^^^^$'
(echo true& echo true2) | grep 'true^^^^^$'
(echo true& echo true2) | grep 'true^^^^^^$'
(echo true& echo true2) | grep 'true$$'
(echo true& echo true2) | grep 'true\^$'
(echo true& echo true2) | grep 'true^\$'
(echo true& echo true2) | grep 'true\\^$'
(echo true& echo true2) | grep 'true\^\$'
(echo true& echo true2) | grep 'true^\\$'
(echo true& echo true2) | grep 'true\^^$'
(echo true& echo true2) | grep 'true^\^$'
(echo true& echo true2) | grep 'true^^\$'
(echo true& echo true2) | grep 'true\\\^$'
(echo true& echo true2) | grep 'true\\^\$'
(echo true& echo true2) | grep 'true\^\\$'
(echo true& echo true2) | grep 'true^\\\$'
(echo true& echo true2) | grep 'true\\^^$'
(echo true& echo true2) | grep 'true\^\^$'
(echo true& echo true2) | grep 'true^\\^$'
(echo true& echo true2) | grep 'true\^^\$'
(echo true& echo true2) | grep 'true^\^\$'
(echo true& echo true2) | grep 'true^^\\$'
(echo true& echo true2) | grep 'true\^^^$'
(echo true& echo true2) | grep 'true^\^^$'
(echo true& echo true2) | grep 'true^^\^$'
(echo true& echo true2) | grep 'true^^^\$'

I also tried each of the above using double quotes instead of single quotes, which also didn't work. Does anyone know how to anchor the regular expression to the end of the line, such that only the first line from my example ("true") matches? Thanks.

2

Cygwin: (echo true; echo true2) | grep true$

GnuWin:(echo true & echo true2) | grep "true $"

In cmd, (echo true & echo true2) actually gives true \r\ntrue2\r\n

  • Ah, nice catch with the whitespace issue. However, your GnuWin approach is still not working for me. Perhaps I missed something: (echo true & echo true2) | grep "true $" still doesn't match anything. – Jeff G Jun 22 '16 at 17:52
  • 1
    @Jeff: bummer... what about | grep -P "true\s+"? – guest-vm Jun 22 '16 at 18:25
  • Yep, that did it for me. Is it that grep doesn't include \r in the \s character class, whereas Perl does? – Jeff G Jun 22 '16 at 18:32
  • It is unfortunate that grep doesn't support multiple patterns with the -P option. In my case, I have to decide between merging all of my regular expressions into one really long one, or use the dirty [[:cntrl:]] hack that I found elsewhere. – Jeff G Jun 22 '16 at 18:39
  • 1
    Late reply: Perl \s = [\t\v\n\f\r ] = grep [[:space:]]. AFAIK, backslash character class is not recognised by grep. – guest-vm Jun 22 '16 at 19:59
0

This turned out to be a combination of problems. (echo true & echo true2) (I edited that mistake out of my question since it wasn't relevant to what I really wanted to know) actually outputs the following on a Windows machine:

true \r\n
true2\r\n

So the first issue is that my echo commands included an extraneous space character. The second issue is that grep treats \n as the end of the line, which is explained in an answer to Why is the end-of-line $ anchor not working with the grep command? So the second problem is that I need to capture the \r character in my regular expression. Therefore, the following is what it takes to get this working:

(echo true& echo true2) | grep 'true[[:space:]]*$'
  • Which version of grep are you using? Mine reports 2.5.3. – Jeff G Jun 22 '16 at 18:44
  • Hmm, that is interesting. I just updated my Cygwin (to 2.9.0, which includes grep 3.0), and I'm still observing that $ only matches \n. Were you running in a Cygwin command prompt, or the Windows command prompt? – Jeff G Dec 12 '17 at 1:57
  • Late Correction: echo true|find "true" matches, (echo true)|find "true " matches. Advice for fellow readers: Windows cmd is FUBAR. – guest-vm Feb 25 '18 at 1:02
  • Also I was wrong on \r\n matched by $ as grep seems to remove all \r from input. – guest-vm Feb 25 '18 at 1:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.