Skip to main content
replaced http://unix.stackexchange.com/ with https://unix.stackexchange.com/
Source Link

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?Why does my shell script choke on whitespace or other special characters?

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?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.

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?Why does my shell script choke on whitespace or other special characters?

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?

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.

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?

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?

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.

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?

fixed typo
Source Link
terdon
  • 252.2k
  • 69
  • 480
  • 718

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 remembedremember 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.

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 remembed 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.

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.

added 1567 characters in body
Source Link
Gilles 'SO- stop being evil'
  • 865.4k
  • 205
  • 1.8k
  • 2.3k

$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: you.

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.

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.

$file | grep -o executes the command specified by the value of file and pipes its output to grep. But that's not what you wanted: 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.

grep -l 'o' -- *

$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.

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.

Source Link
Gilles 'SO- stop being evil'
  • 865.4k
  • 205
  • 1.8k
  • 2.3k
Loading