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
Are
ls | grep *e*
andls | 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.
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.