views:

142

answers:

3

How can I replace a particular term in multiple files in Linux?

For instance, I have a number of files in my directory:

file1.txt file2.txt file3.txt

And I need to find a word "searchword" and replace it with "replaceword".

+4  A: 

Nothing spectacular but thought this might be of help to others. Though you can write a shell script to do this easily, this one-liner is perhaps easier:

grep -lr -e '<searchthis>' * | xargs sed -i 's/<searchthis>/<replacewith>/g'
Legend
You can also just do `sed 's<searchthis>/<replacewith>/g' -i *`
Alex JL
Ah... even simpler.. :) Thanks!
Legend
@Code Duck - this will avoid invoking `sed` where there is no search term present. More efficient - I guess - when the files are large.
Tom Duckering
@ Tom Duckering : I thought of that too, but then realized the first example is greping through each file in the directory to find the term, too. Sed may or may not be as efficient as grep at doing that, but anyhow it seems simpler to just use one command.
Alex JL
@Code Duck - yeah - the usual trade one makes in adding complexity to make something more efficient. :)
Tom Duckering
It's unclear whether searching through the files with grep is more efficient than searching through the files with sed. Either way, every line of each file is being sifted through.
Alex JL
@ Tom Duckering: Actually, the grep/xargs/sed one is less efficient: you are opening every file, searching it, then reopening matching files with sed. With the sed only style, you are simply opening every file. So, it's like O(n+x) vs. O(n).
Alex JL
+6  A: 
sed -i.bak 's/searchword/replaceword/g' file*.txt
# Or sed -i.bak '/searchword/s/searchword/replaceword/g' file*.txt

With bash 4.0, you can do recursive search for files

#!/bin/bash
shopt -s globstar
for file in **/file*.txt
do 
  sed -i.bak 's/searchword/replaceword/g' $file
  # or sed -i.bak '/searchword/s/searchword/replaceword/g' $file
done

Or with GNU find

find /path -type f -iname "file*.txt" -exec sed -i.bak 's/searchword/replace/g' "{}" +;
ghostdog74
The second option can be shortened to sed -i.bak '/searchword/s//replaceword/g'
William Pursell
the second option traverse subdirectories.
ghostdog74
@ghostdog: You miss the point of my comment. With sed, you do not need to specify the searchword twice.
William Pursell
+1  A: 

Use an ed script

Although sed now has an in-place edit option, you can also use the ed or ex program for this purpose...

for i in "$@"; do ed "$i" << \eof; done
1,$s/searchword/replaceword/g
w
q
eof
DigitalRoss