We help IT Professionals succeed at work.

Replace a string in several text files

145,125 Views
Last Modified: 2013-11-18
I want to replace a string with another string in several text files. I tried the following command which I read from a Linux book, but it doesn't work. Can anyone give me some help?

[Linux]#find ./ -type f -exec sed 's/string1/string2' {} \;
Comment
Watch Question

Commented:
This problem has been solved!
(Unlock this solution with a 7-day Free Trial)
UNLOCK SOLUTION

Commented:
or maybe:


   To do an entire directory tree, use the Unix utility find, like so
   (thanks to Jim Dennis <jadestar@rahul.net> for this script):

      #! /bin/sh
      # filename: replaceall
      find . -type f -name '*.txt' -print | while read i
      do
         sed 's|foo|bar|g' $i > $i.tmp && mv $i.tmp $i
      done

   This previous shell script recurses through the directory tree,
   finding only files in the directory (not symbolic links, which will
   be encountered by the shell command "for file in *.txt", above). To
   preserve file permissions and make backup copies, use the 2-line cp
   routine of the earlier script instead of "sed ... && mv ...". By
   replacing the sed command 's|foo|bar|g' with something like

      sed "s|$1|$2|g" ${i}.bak > $i

   using double quotes instead of single quotes, the user can also
   employ positional parameters on the shell script command tail, thus
   reusing the script from time to time. For example,

      replaceall East West

   would modify all your *.txt files in the current directory.

Author

Commented:
Comment accepted as answer

Commented:
i know this q is old, but here's and easy way to do this in one line(if you have perl installed):


perl -pi -e "s/search/replace/g;" *.txt


you could use find or xargs to get fancy with finding the files you want to change.

Commented:
Can I use a variable as the string instead?
ie.
sed 's/string1/$string2/g' $fl.old > $fl
where $string2 is a variable,

I find it doesn't work

Commented:
The sed substitution has a syntax error. It is missing the final '/' and should be written as:
find ./ -type f -exec sed 's/string1/string2/' {} \;

I don't have my Linux box up right now but this works fine in OpenBSD and cygwin.

It will only change the first occurance of string1 on each line so you might want to add 'g' to the end of the substitution command to get all occurances:
find ./ -type f -exec sed 's/string1/string2/g' {} \;

And you might not want to sed every file but just some that have certain names or extensions:
find ./ -name "*.txt" -exec sed 's/string1/string2/g' {} \;

Commented:
Oops, I forgot to include the -i so sed edits in-place:
find ./ -type f -exec sed -i 's/string1/string2/' {} \;
In response to :

"Comment from Fzzy
Date: 04/16/2003 08:01AM CDT
you could use find or xargs to get fancy with finding the files you want to change."

I've found this to work well as a one liner, recursive, search and replace for Linux.

find ./ -type f | xargs perl -pi -w -e 's/SEARCH/REPLACE/g;'

It is handy for mass updates to websites.  Be careful and use your grep -r 'SEARCH' *.* first to make sure you are only grabbing the files you want.

-Mike Putnam