This is what I tried:

find . -name *.sv | xargs sed -i -e '<command>' -e '<command>'

It does not work. Using the exact same command on each file still works.

Thanks for the help.

  • 2
    Define 'does not work'. What specifically does it do?
    – DopeGhoti
    Jun 5, 2018 at 18:37

3 Answers 3


To force xargs to only execute sed with a single file at a time, use -n 1 with xargs. You should also pass the pathnames from find using -print0 and get xargs to receive them with -0 (if your find and xargs supports these nonstandard options), so that pathnames containing spaces etc. are handled correctly. You probably also need to specify that you are looking for regular files (and not directories etc.) and you definitely need to quote that shell glob (or it may expand to any matching filename in the current directory):

find . -type f -name '*.sv' -print0 | xargs -0 -n 1 sed -i -e '<command>' -e '<command>'

Or, just use find:

find . -type f -name '*.sv' -exec sed -i -e '<command>' -e '<command>' {} ';'


A solution that is not using find, but instead uses the ** globbing pattern (matches "recursively" down into subdirectories) available in bash after doing shopt -s globstar:

shopt -s globstar dotglob nullglob
for pathname in ./**/*.sv; do
    if [[ -f "$pathname" ]] && [[ ! -h "$pathname" ]]; then
        sed -i -e '<command> -e '<command>' "$pathname"

This loop loops over all files that have a filename suffix .sv and tests whether each matched name is a regular file (we have to test separately with ! -h to make sure its not a symbolic link to a regular file) before applying the sed command. The shell options enable the use of ** (globstar), matching of hidden names (dotglob), and removes the patterns completely if it does not match (nullglob).

Or, with the zsh shell, which has ** enabled by default, and can use a "glob qualifier" to do most of the "extra" work that bash has to do explicitly:

for pathname in ./**/.sv(.DN); do
    sed -i -e '<command> -e '<command>' "$pathname"

The glob qualifier (.DN) modifies the preceding globbing pattern so that it matches only regular files, matches hidden names, and expands to nothing if there is no match at all.

  • At least for GNU sed, doesn't -i imply -s (i.e. that sed will treat the files as separate, even if xargs doesn't)? Jun 5, 2018 at 19:15
  • @steeldriver Possibly, I don't use GNU sed very often (and never with -i). The original command may still have issues with whitespace in file names though (and the other issues).
    – Kusalananda
    Jun 5, 2018 at 19:31
  • @Kusalananda I would also recommend combining both of the -e options on the sed. -e denotes a sed script will follow, not a sed command. sed -e '<command1> ; <command2>' FILE works just fine.
    – Centimane
    Jun 6, 2018 at 10:25
  • @Centimane If you want to get technical about it, -e denotes that the following argument is a sed expression or command. -f is used to read a script from a file. There is no benefit to combining the arguments of several -e into a single string, and in some cases, it's even impossible to do so.
    – Kusalananda
    Jun 6, 2018 at 11:12
  • @Kusalananda -e denotes a script as per the man page: "add the script to the commands to be executed". I don't think there are any cases where it's impossible, you just might have to escape some characters if using double-quotes instead of single. It is true though that the result is the same, but it's good to recognize that -e is for passing a script rather than a single command.
    – Centimane
    Jun 6, 2018 at 11:48

Here is another method that worked for me:

find -name "*.fail" | xargs -L 1 sed -i -e 's/cse/ecs/g' -e 's/trex/dino/g'
  • This might work for you, but as a generic solution this would fail on files and directories that have newlines in their name.
    – Kusalananda
    Oct 30, 2019 at 8:10

this worked for me grep -rl foo | xargs sed -i 's/foo/bar'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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