I recently came across a typo that existed in a bunch of html files on my web server. I thought it should be easy enough to change, but since it was in a number of files, editing it by hand would be time consuming. Fortunately, there is an easy, one liner command to replace the text in multiple files in a sub directory using recursion.

grep -lr -e '<oldword>' * | xargs sed -i 's/<oldword>/<newword>/g'

This command broken down:

  • grep for the word in a files, use recursion (to find files in sub directories), and list only file matches
  • | xargs passes the results from the grep command to sed
  • sed -i uses a regular expression (regex) to evaluate the change: s (search) / search word / target word / g (global replace)

For more information, see man pages for grep, sed, and xarg. Also it is very handy to learn about regular expressions as they are a valuable tool to any command line programmer!

Update 2009/7/19:

Thanks to reader btr we have a great one-line perl command that will perform the same task:

Perl provides a really nice one-line for this kind of thing:

perl -p -i -e ’s///g’ *

It also provides the option of creating a backup of each file changed:

perl -p -i.bak -e ’s///g’ *

mnemonic: PIE (”easy as pie”, etc.)
google “perl pie” and you’ll get lots of info for other uses of this technique.

http://www.linux.org/lessons/short/perlpie/perl_pie.html

15 comments
  1. Pingback: Dave Drager
  2. Pingback: tom howard
  3. Perl provides a really nice one-line for this kind of thing:

    perl -p -i -e ‘s///g’ *

    It also provides the option of creating a backup of each file changed:

    perl -p -i.bak -e ‘s///g’ *

    mnemonic: PIE (“easy as pie”, etc.)
    google “perl pie” and you’ll get lots of info for other uses of this technique.

    http://www.linux.org/lessons/short/perlpie/perl_pie.html

  4. Perl provides a really nice one-line for this kind of thing:

    perl -p -i -e ‘s///g’ *

    It also provides the option of creating a backup of each file changed:

    perl -p -i.bak -e ‘s///g’ *

    mnemonic: PIE (“easy as pie”, etc.)
    google “perl pie” and you’ll get lots of info for other uses of this technique.

    http://www.linux.org/lessons/short/perlpie/perl_pie.html

  5. Pingback: Dave Drager
  6. Pingback: Matthew Lanham
  7. Thanks for the tip!
    One thing though, it doesn’t work with filenames containing spaces; here’s an updated version:

    grep -lZr -e ” * | xargs -0 sed -i ‘s///g’

    Also, it might be worth noting that the first search string (the first ”) can be written without any escaping, but that the next two strings (/) have to be escaped for use in a regular expression, that is, having . ( ) [ ] ? * and / being prefixed by a (e.g. “/home/user/” becomes “/home/user/”)

  8. Thanks for the tip!
    One thing though, it doesn’t work with filenames containing spaces; here’s an updated version:

    grep -lZr -e ” * | xargs -0 sed -i ‘s///g’

    Also, it might be worth noting that the first search string (the first ”) can be written without any escaping, but that the next two strings (/) have to be escaped for use in a regular expression, that is, having . ( ) [ ] ? * and / being prefixed by a \ (e.g. “/home/user/” becomes “\/home\/user\/”)

Comments are closed.

You May Also Like

Network Solutions worldnic.com nameservers down

Network Solutions worldnic.com nameservers both appear down. Pings get through occasionally, this…

Centos, Logrotate, and noexec

This seems like a pretty rare bug but annoying anyway. On my…

Simple Guide To Signing RPMs with FPM

I’ve been using the excellent fpm (Effing package manager!) tool for automatically…

Prompt to confirm copy even with cp -f?

Wow – I get so frustrated when I try to copy some…