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.

0

2 Answers 2

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

7
  • 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, 2016 at 17:52
  • 1
    @Jeff: bummer... what about | grep -P "true\s+"?
    – guest
    Jun 22, 2016 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, 2016 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, 2016 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
    Jun 22, 2016 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:]]*$'
4
  • Which version of grep are you using? Mine reports 2.5.3.
    – Jeff G
    Jun 22, 2016 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, 2017 at 1:57
  • Late Correction: echo true|find "true" matches, (echo true)|find "true " matches. Advice for fellow readers: Windows cmd is FUBAR.
    – guest
    Feb 25, 2018 at 1:02
  • Also I was wrong on \r\n matched by $ as grep seems to remove all \r from input.
    – guest
    Feb 25, 2018 at 1:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .