views:

2318

answers:

5

I need to recursively search directories and replace a string (say http://development:port/URI) with another (say http://production:port/URI) in all the files where ever it's found. Can anyone help?

It would be much better if that script can print out the files that it modified and takes the search/replace patterns as input parameters.

Regards.

+2  A: 

It sounds like you would benefit from a layer of indirection. (But then, who wouldn't?)

I'm thinking that you could have the special string in just one location. Either reference the configuration settings at runtime, or generate these files with the correct string at build time.

Jay Bazuzi
+4  A: 

Try this:

find . -type f | xargs grep -l development | xargs perl -i.bak -p -e 's(http://development)(http://production)g'

Another approach with slightly more feedback:

find . -type f | while read file
do
    grep development $file && echo "modifying $file" && perl -i.bak -p -e 's(http://development)(http://prodution)g' $file
done

Hope this helps.

toolkit
Note that the old files will be saved as *.bak, which indirectly satisfies the requirement: "print out the files that it modified".
Jon Ericson
+6  A: 

find . -type f | xargs sed -i s/pattern/replacement/g

indentation
an extra note: you have to escape quotation marks with backslashes in the pattern: ... sed -i s/\"hello\"/hi/g
nickf
goooooooooooooood!
flybywire
A: 

Use zsh so with advanced globing you can use only one command. E.g.:

sed -i 's:pattern:target:g' ./**

HTH

Zsolt Botykai
A: 

Don't try the above within a working svn/cvs directory, since it will also patch the .svn/.cvs, which is definitely not what you want. To avoid .svn modifications, for example, use find . -type f | fgrep -v .svn | xargs sed -i 's/pattern/replacement/g'