4

I have a file that has unique lines that start with 2 stars (**).

However when I run a grep command for

grep \*\* fileName 

I get all of the lines in the file. This is very unusual, and what I see as non-matching lines do not contain **.

How would I escape the ** for the correct lines to be found?

5

So try :

egrep "^\*\*" YOUR_FILE

Don't forget to use double quote.

Note: Use egrep instead of grep.

  • 1
    That was the reason why... I'm not sure why it behaved differently because I had quotes versus no qoutes. – monksy Aug 17 '13 at 2:18
  • 1
    Unfortunately, i just can say , implementation of grep family,such as fgrep, egrep are weak.If you want to use regular expression, use awk interprreter. – PersianGulf Aug 17 '13 at 2:47
  • 5
    egrep is not standard. grep -E is the one you want to use if you want extended regular expressions as in awk. However, ^\*\* is the same in basic regular expressions and extended regular expressions. So grep '^\*\*' is just as fine. – Stéphane Chazelas Aug 17 '13 at 20:07
  • I actually use single quotes for this to work!! – David Okwii Jul 22 '16 at 9:16
6

You can also achieve the same thing by instructing grep that the string it's to match is a fixed string. The switch to do this is -F or --fixed-strings.

-F, --fixed-strings
          Interpret  PATTERN  as  a  list of fixed strings, separated by 
          newlines, any of which is to be matched.  (-F is specified by
          POSIX.)

So something like this will do it:

$ grep -F "**" somefile.txt

Example

$ cat somefile.txt
** blah
blahblah
** hi

Grepping the file produces this:

$ grep -F "**" somefile.txt
** blah
** hi
5

In:

grep \*\* fileName

The backslashes are used to escape the * in the shell (where * is a globbing operator).

What grep receives as its second argument is a string of two characters: **.

As a regular expression, that means any (0 or more) number of star characters, so basically it matches everywhere since it also matches the empty string which explains why you get all the lines of the file.

Because * is special to grep regex as well, you need to escape it there as well. Best is to use single quotes instead of backslashes to escape * to the shell (because single quotes are strong shell quotes that escape every character but the single quote character itself), and use backslashes to escape * to grep. Double quotes would work as well in that instance, but beware that backslashes are still special to the shell inside double quotes.

So:

grep '\*\*' somefile.txt

(with * escaped so they're no longer regex operators but considered as literal characters) would return the lines of somefile.txt that contain a sequence of 2 star characters. If you want them to be found only at the beginning of the line, you've got to use the anchoring regex operator ^:

grep '^\*\*' somefile.txt

An alternative way for * not to be taken as a regex operator would be to use character ranges:

grep '^[*][*]' somefile.txt

An alternative way to specify two star characters is to write it:

grep '^\*\{2\}' somefile.txt

(where \{ is another regex operator) which is easier to read if you use extended regular expressions as when passing the -E option to grep (avoid egrep as it's not standard):

grep -E '^\*{2}' somefile.txt

(in extended regular expressions, { is the regex operator).

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.