Grep -l output filenames with spaces

bashgreppathsed

I want to loop over files with

for f in `grep -rsl "foo" . `: do sed -i -- "s/foo/bar/g" $f; done;

But since filenames contain spaces, a filename is split whenever a space is found.

How can I pass the filename with its spaces to the do block?

Best Answer

For dealing with difficult file names, it is best to separate the file names with NUL characters. GNU grep supports this with the --null option and xargs supports this with the -0 option. Thus, try:

grep --null -rslZ "foo" | xargs -0 sed -i -- "s/foo/bar/g"

Using a shell loop

grep --null -rslZ "foo" | while IFS= read -r -d $'\0' file
    do 
        sed -i -- "s/foo/bar/g" "$file"
    done
Related Question