2

I am using a simple text file to test the * meta-character through grep. The text file is as below:

1
11
111
1111
11111
111111

d
da
daa
daaa

b
bc
bcc
bccc

Now when I search digit 1 using grep like this:

grep 1* regex.txt

output is

1
11
111
1111
11111
111111

d
da
daa
daaa

b
bc
bcc
bccc

Even in the case of character 'd' the result is same with highlighted 'd' in red BUT in the case of character 'a' & 'b' there is no output for the following search command:

grep a* regex.txt
grep b* regex.txt

AND the below commands give expected output

grep "a*" regex.txt
grep "b*" regex.txt

Why so? Why is bash partial towards the character 'd' and not to 'a' & 'b'

  • 2
    Without quotes * is expanded by shell path. If there is no output for a* try echo a* and you should see files with names started with a (same b) – Costas Nov 14 '15 at 9:57
  • 1. quote your regexps so the shell doesn't interpret them as wildcard globs. 2. regexps are not wildcard globs. * means zero-or-more of the last character/sub-expression. It does not mean "followed by anything" as it does in a shell wildcard. – cas Nov 14 '15 at 10:16
  • Please don't edit your question to add a second question. Post a new question instead. I also suggest you read a basic primer on regular expressions to understand how they work a bit better. Try regular-expressions.info. – terdon Nov 14 '15 at 12:10
3

This is happening because the a* and b* are not quoted and, therefore, are expanded by the shell before being passed to grep. For example, consider this directory:

$ ls    
afile.txt bfile.txt regex.txt

If I try to run grep a* regex.txt, the a* will become afile.txt and that is what will be given as a search pattern to grep. We can use bash's debugging option (set -x) to demonstrate:

$ set -x
$ grep a* regex.txt
+ grep --color afile.txt regex.txt

The reason it worked for d and not for a or b is that you have a files or directories whose names start with a and b in your current directory. If you didn't, it would have worked:

$ ls
afile.txt bfile.txt regex.txt
$ grep a* regex.txt  ## no output, it's searching for 'afile.txt'
$ rm afile.txt       ## now there are no filenames starting with a
$ grep a* regex.txt
1
11
111
1111
11111
111111

d
da
daa
daaa

b
bc
bcc
bccc

To avoid this, always quote your search patterns:

grep "a*" regex.txt

Or

grep 'a*' regex.txt

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.