$file | grep -o
executes the command specified by the value of file
and pipes its output to grep
. But that's clearly not what you wanted.
If you want to list files that contain o
You meant the value of file
to be an input file for grep
, not a command to execute. So you need an input redirection, not a pipe.
if grep 'o' <"$file"
grep
reads from standard input if it doesn't receive a file name on its command line. You can also pass a file name on the command line; this does the same thing.
if grep 'o' -- "$file"
For why the double quotes, and why the --
in the second method, see Why does my shell script choke on whitespace or other special characters?
To suppress the output from grep
, use the -q
option, or redirect the output to /dev/null
.
if grep -q 'o' <"$file"
or
if grep 'o' <"$file" >/dev/null
Another problem with your script is that command=`ls -l`
sets the variable command
to the output of the command ls -l
, which is not a list of file names. If you recall Why does my shell script choke on whitespace or other special characters?, you'll remember that it's impossible to store a list of file names in a string variable: all the file names are jumbled together. Here, it's even worse: there's junk like permissions, dates, etc. The way to get a list of file names in a shell script is to use a wildcard pattern.
for file in *
do
if grep -q 'o' <"$file"
then
echo "$file"
fi
done
All of this is equivalent to
grep -l 'o' -- *
If you want to list files whose name contains o
This feature is built into the shell, with wildcard patterns. The pattern *o*
matches file names that contain o
, so to list them, you only need
ls -l -- *o*
The --
is necessary in case one of the file names begins with -
, otherwise ls
might interpret the file name as an option.
If this is a learning exercise on the use of grep
, and you want to pass the file name as input to grep
, you need to use the echo
command.
echo "$file" | grep 'o'
The echo
command might mangle some file names. To be safe, use printf
. For more on this, and on the use of double quotes, see Why does my shell script choke on whitespace or other special characters?
printf '%s\n' "$file" | grep 'o'
As above, don't parse the output of ls
.
for file in *
do
if printf '%s\n' "$file" | grep -q 'o'
then
printf '%s\n'
fi
done
If your file names don't contain any newlines, you could reduce this to.
for file in *
do
printf '%s\n' "$file" | grep 'o'
done
Once again, the loop is pointless here and you can just use
printf '%s\n' *o*
to print the matching file names on separate lines. The use of grep
would only be justified if you needed a regular expression that your shell's wildcard patterns aren't powerful enough to express.
ls -l *o*
? – jimmij May 24 '15 at 23:46find . -maxdepth 1 -name "*o*"
– jimmij May 24 '15 at 23:51o
, or the names of the files whose content containso
? – Gilles 'SO- stop being evil' May 24 '15 at 23:52