Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

So I want to change several files at one with one command. This is what I have so far:

find -regex ".*\.ext$" | xargs grep -l searchText 2> /dev/null | xargs -i sed 's/searchText/replaceText/' > {}.new

What it does:

I find files with extension ext, send it to grep ignoring errors, and then send it to sed for replacement with new filename file.ext.new.

The problem seems to be that the redirect > in the sed prevents the {} from being replaced with the filename.

Any ideas? or a better solution?

share|improve this question
add comment

5 Answers

up vote 3 down vote accepted

If you can live with the file being updated in place and a backup created.

find -name '*.ext' -exec sed -i'.backup' 's/searchText/replaceText/' {} +

Edit:

If you absolutely can't have the files that way round - modified file in place and original with an extension - then you could bolt an extra command on the end of the exec to move them around.

share|improve this answer
    
+1 Good stuff. Still want to send through grep to make sure I don't end up modding unnecessary files. Otherwise, it will change the timestamp and leave lots of backups of unmodified files. –  Keith Bentrup Aug 13 '09 at 17:07
add comment

Backticks aka. "External commands" to the rescue.

sed -i '.bak' 's/searchText/replaceText/g' `grep -l searchText \`find . -name '*.ext'\``

Here we have find searching for '*.ext' which is then given as files to search for grep which are the given to sed which does the actual replacing. It has the advantage that it doesn't spawn new grep process for every file that is found. Ditto for sed.

share|improve this answer
add comment

sed has a --in-place option.

share|improve this answer
add comment

Perl rocks for this:

find . -type f -name '*.ext' | xargs perl -pi.bak -e 's/searchText/replaceText/g'
share|improve this answer
add comment

Yeah, Perl rocks for this and here is a whole script for this purpose.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.