Grep and replace a text string in matching files

After a bit of searching and trying a few different methods, I’ve settled on the following commands to find and replace a text string in all files that match the search string identified through grep.

Here’s the full command (adjust the values of ‘searchtext’, ‘matchtext’ and ‘replacetext’ accordingly).

$ grep -r -l 'searchtext' . | sort | uniq | xargs perl -e "s/matchtext/replacetext/" -pi

Here’s a break down of how it works from left to right:

$ grep -r -l 'searchtext' .

Finds and lists all files in the current directory (and all subdirectories recursively) that match the value of ‘searchtext’.

$ | sort | uniq

This pipes the grep results to sort which sorts the results. The results are then piped to uniq to filter out any duplicates

$ | xargs perl -e "s/matchtext/replacetext/" -pi

Unique grep results from previous commands are piped to xargs so that the perl command can be executed against them.

The perl -e flag executes a regex search for the string ‘matchtext’ and replaces it with ‘replacetext’ using “s/matchtext/replacetext/” on each file it receives from the grep results. The -pi flag edits the file in place – i.e., saves the change of replacing ‘matchtext’ with ‘replacetext’ in each file. Note you can use variations on -pi to save to a new file if that is what you are after.