13

I have this shell script to update IP addresses in my configuration files (any that match $old_address_pattern must be changed to $new_address):

grep -rl "$old_address_pattern" /etc \
  | xargs sed -i "s/$old_address_pattern/$new_address/g"

If the grep command finds no matching files, then sed will complain 'no input files'. How can I make this pipeline succeed when the list of files is empty?

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
qurat
  • 439
  • 1
  • 7
  • 14

1 Answers1

19

If you want to avoid running sed when grep produces no output, then (since you've tagged this with Ubuntu), you can give the -r or --no-run-if-empty argument to xargs:

--no-run-if-empty
-r
If the standard input does not contain any nonblanks, do not run the command. Normally, the command is run once even if there is no input. This option is a GNU extension.

So your command should look like:

grep -rlZ "$old" /etc | xargs -0 -r sed -i "s/$old/$new/g"

(I added grep -Z and xargs -0 flags, since these are supported on your platform, and they make the commands more robust to malicious filenames)


For platforms without xargs -r, then the usual solution is to pass /dev/null as a first filename argument:

grep -rl "$old" /etc | xargs sed -i "s/$old/$new/g" /dev/null

In this case, when there are no matches, sed will operate harmlessly on the null device.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103