grep str1 -rl .
generates the list of all files that contain str1
. That list is simply too long. This is not a problem of sed
or grep
, but the amount of space your system provides to parameters. A discussion of the "argument list too long" error can be found on this same forum.
One way of fixing that is with xargs
:
grep -rl str1 . | xargs sed -i 's/str1/str2/'
xargs
takes its input and calls sed
repeatedly with appropriately sized portions of the entire input.
Since we don't know if there are weird filenames that contain special characters like spaces, ";", "|" and the like, a better way might be
find . -type f -exec sed -i 's/str1/str2/' {} \;
find
goes through all regular files and performs the substitution if the file contains str1. Calling grep
to check if the file does contain str1 is wasteful.
Note that these solutions, like your original question, assume that all files can be processed with sed
, i.e. they are text files. If you are not sure about that, this code only runs sed
after confirming that the file is a text file:
find . -type f -exec sh -c "file {} | grep -q text && sed -i 's/str1/str2/' {}" \;