1

When used ls | grep *e* gives much lesser result than ls | grep e, why is it so. Are they not the same commands. Anybody knows the difference between these commands.

2 Answers 2

1

Are ls | grep *e* and ls | grep e not the same commands?

No, they are different. With

$ ls | grep *e*

the command shell expands the pattern *e* to match all files which contain the letter e in the current directory. This expanded file list is then passed to the grep command:

$ ls
Hello.txt  Null.txt  Sample.txt

When executing

$ ls | grep *e*

the actual command will be ls | grep Hello.txt Sample.txt

With

$ ls | grep e

there is no file name expansion and the actual command will be ls | grep e.

See also

If you want to pass the parameter without being expanded, you need to quote it:

$ ls | grep "*e*"

Then, the command actually will be ls | grep *e* (with "*e*" being passed as argv[1] to the grep command).

Note that the shell expansion is different from a regular expression - the shell matches any string for *, while in regular expressions * denotes that any number of the previous expression shall occur.

0
0

The shell expands *e* before executing the command. So if you have files named beer and free, you end up grepping for beer in free, and ignoring the input from ls.

*e* is not a valid regular expression, anyway. * means "zero or more of the preceding expression" and there is no preceding expression in the first instance. Properly, grep should display an error for this, but doesn't. It ends up matching nothing repeated zero or more times, followed by e repeated zero or more times. Because every imaginable input contains zero or more occurrences of e, it would end up matching every input line.

But anyhow, as noted above, grep would not see this input, because it is intercepted and expanded by the shell. If you want to use * literally, you need to quote it.

ls | grep '.*e.*'

is just a really lame way to say

ls | grep 'e'

because the leading and trailing wildcards add no value -- grep always looks for a match anywhere on each input line.

What you actually want is to use the wildcard matching features of the shell:

ls *e*

The glob expression *e* is not a regular expression, but a glob pattern. It does what you apparently expect.

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