views:

679

answers:

2

Hey dudes,

what's the best way to do this? i'm no command line warrior, but i was thinking there's possibly a way using grep and cat.

i just want to replace a string that occurs in a folder and sub-folders. what's the best way to do this? i'm running ubuntu if that matters.

-d

+8  A: 
find . -type f -print0 | xargs -0 -n 1 sed -i -e 's/from/to/g'

The first part of that is a find command to find the files you want to change. You may need to modify that appropriately. The "xargs" command takes every file the find found and applies the "sed" command to it. The "sed" command takes every instance of "from" and replaces it with "to". That's a standard regular expression, so modify it as you need.

Paul Tomblin
it doesn't seem like this command is recursing into subdirectories. is there something i'm doing wrong?
blackrobot
What makes you think it's not recursing into directories?
Paul Tomblin
the text files in the subdirectories are not making the changes. what i want it to do is this: change occurrences of some.ip.address to somewebsite.com in all subdirs.
blackrobot
Replace the "sed" with "echo" and make sure it's finding all your files.
Paul Tomblin
If that change shows you that it's finding your files, then the fault is in your regular expression. Post what you're using in the 's/some.ip.address/somewebsite.com/g' part of the sed command.
Paul Tomblin
for the sed part i'm using: find . -type f -print0 | xargs -0 -n 1 sed -i -e 's/some.\ip\.address/somewebsite\.com/g'
blackrobot
* i meant "some\.ip\.address"...
blackrobot
Try "find . -type f -print0 | xargs -0 -n 1 grep -l 'some\.ip\.address'" to see if it's actually finding your ip address.
Paul Tomblin
It's also possible you have an old version of sed that doesn't support -i.
Paul Tomblin
if i look at sed --help, it shows this:-i[SUFFIX], --in-place[=SUFFIX]edit files in place (makes backup if extension supplied)
blackrobot
i'm sure i'll get it working, thanks for your help!
blackrobot
+2  A: 

As Paul said, you want to first find the files you want to edit and then edit them. An alternative to using find is to use GNU grep (the default on Ubuntu), e.g.:

grep -r -l from . | xargs -0 -n 1 sed -i -e 's/from/to/g'

You can also use ack-grep (sudo apt-get install ack-grep or visit http://petdance.com/ack/) as well, if you know you only want a certain type of file, and want to ignore things in version control directories. e.g., if you only want text files,

ack -l --text from | xargs -0 -n 1 sed -i -e 's/from/to/g'

An alternative to using sed is to use perl which can process multiple files per command, e.g.,

grep -r -l from . | xargs perl -pi.bak -e 's/from/to/g'

Here, perl is told to edit in place, making a .bak file first.

You can combine any of the left-hand sides of the pipe with the right-hand sides, depending on your preference.

Emil
You can avoid version control directories in "find" using the "-prune" command. For instance "find . -name RCS -prune -o -type f -print0"
Paul Tomblin
True, though it requires less brainpower to have a tool like ack handle it for you.
Emil