91

grep fails when using both --ignore-case and --only-match options. Example:

$ echo "abc" | grep -io abc
abc
$ echo "ABC" | grep -io abc
$ 

But

$ echo "abc" | grep -i abc
abc
$ echo "ABC" | grep -i abc
ABC

According to man page:

   -o, --only-matching
          Show only the part of a matching line that matches PATTERN.
   -i, --ignore-case
          Ignore case distinctions in both the PATTERN and the input files.

Is it a bug of grep or I didn't get the map page?

I am using Mac OS X 10.6.8 and

$ grep --version
grep (GNU grep) 2.5.1

Found this link: http://lists.gnu.org/archive/html/bug-gnu-utils/2003-11/msg00040.html

Of course it is possible to use workaround like grep -o [aA][bB][cC], but this doesn't seem to be a good option.

schatten
  • 1,497
  • 1
  • 12
  • 19

4 Answers4

53

This is a known bug on the initial 2.5.1, and has been fixed in early 2007 (Redhat 2.5.1-5) according to the bug reports. Unfortunately Apple is still using 2.5.1 even on Mac OS X 10.7.2.

You could get a newer version via Homebrew (3.0) or MacPorts (2.26) or fink (3.0-1).


Edit: Apparently it has been fixed on OS X 10.11 (or maybe earlier), even though the grep version reported is still 2.5.1.

kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
19

It could be a problem in your version of grep.

Your test cases are working correctly here on my machine:

$ echo "abc" | grep -io abc
abc
$ echo "ABC" | grep -io abc
ABC

And my version is:

$ grep --version
grep (GNU grep) 2.10
inspirednz
  • 4,807
  • 3
  • 22
  • 30
Felix Yan
  • 14,841
  • 7
  • 48
  • 61
2

If your grep -i does not work then try using tr command to convert the the output of your file to lower case and then pipe it into standard grep with whatever you are looking for. (it sounds complicated but the actual command which I have provided for you is not !).

Notice the tr command does not change the content of your original file, it just converts it just before it feeds it into grep.

1.here is how you can do this on a file

tr '[:upper:]' '[:lower:]' <your_file.txt|grep what_ever_you_are_searching_in_lower_case

2.or in your case if you are just echoing something

echo "ABC"|tr '[:upper:]' '[:lower:]' | grep abc
grepit
  • 21,260
  • 6
  • 105
  • 81
  • It does not change the content, but it changes the piped stream, so you will not get an original matching content of the file. – schatten Jan 16 '13 at 06:38
1

I'd suggest that the -i means it does match "ABC", but the difference is in the output. -i doesn't manipulate the input, so it won't change "ABC" to "abc" because you specified "abc" as the pattern. -o says it only shows the part of the output that matches the pattern specified, it doesn't say about matching input.

The output of echo "ABC" | grep -i abc is ABC, the -o shows output matching "abc" so nothing shows:

Naos:~ mattlacey$ echo "ABC" | grep -i abc | grep -o abc
Naos:~ mattlacey$ echo "ABC" | grep -i abc | grep -o ABC
ABC
Matt Lacey
  • 8,227
  • 35
  • 58