4

I have a hierarchy of directories containing many text files. I would like to search for a particular text string every time it comes up in one of the files, and replace it with another string. For example, I may want to replace every occurrence of the string "Coke" with "Pepsi". Does anyone know how to do this? I am wondering if there is some sort of Bash command that can do this without having to load all these files in an editor, or come up with a more complex script to do it.

I found this page explaining a trick using sed, but it doesn't seem to work in files in subdirectories.

2
  • 1
    I hate it when this happens. Four answers that are very close in under 3 minutes. Sometimes answering these questions becomes a race... very stresfull... waiting for the yellow bar at the top saying "load answers" Commented May 18, 2010 at 19:04
  • Many of you submitted suggestions that worked. I accepted theatrus's simply because he replied first. Commented May 18, 2010 at 19:25

7 Answers 7

15

Use sed in combination with find. For instance:

find . -name "*.txt" | xargs sed -i s/Coke/Pepsi/g

or

find . -name "*.txt" -exec sed -i s/Coke/Pepsi/g {} \;

(See the man page on find for more information)

Sign up to request clarification or add additional context in comments.

3 Comments

also,if you're using a combination of find and xargs, particularly in a script, it's always best to use find -print0 and xargs -0, to guard against files with spaces in their names
@mikez302: Please take Martin's comment into account. xargs is often not required and should usually be used with the -0 switch. The second solution is much better.
find also has the option to spawn only a single process for all results if you use + instead of ; as the delimiter to -exec: find . -name '*.txt' -exec sed -i 's/Coke/Pepsi/g' '{}' +
4

IMO, the tool with the easiest usage for this task is rpl:

rpl -R Coke Pepsi .

(-R is for recursive replacement in all subdirectories)

2 Comments

@Dennis: Thanks! I should have thought about adding at least one of them.
3

Combine sed with find like this:

find . -name "file.*" -exec sed -i 's/Coke/Pepsi/g' {} \;

Comments

3

find . -type f -exec sed -i 's/old-word/new-word/g' {} \;

Comments

2

I usually do it in perl. However watch out - it uses regexps which are much more powerful then normal string substitution:

% perl -pi -e 's/Coke/Pepsi/g;' $filename

EDIT I forgot about subdirectories

% find ./ -exec perl -pi -e 's/Coke/Pepsi/g;' {} \;

Comments

2

you want a combination of find and sed

Comments

0

You may also:

Search & replace with find & ed

http://codesnippets.joyent.com/posts/show/2299

(which also features a test mode via -t flag)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.