Federico Cargnelutti

Simple is better than complex. Complex is better than complicated. | @fedecarg

The easiest way to search and replace in files

with 4 comments

The “find” command is one of the most powerful and useful Unix commands, you can use it to locate files, and then perform some type of action on the files after they’ve been located. With this capability, you can locate files using powerful search criteria, and then run any Unix command you want on the files you locate.

Find Strings

In the following example I’ll recursively search a directory for files containing the ‘test’ string and output the name of the files and the line number:

$ grep -in -e 'test' `find -type f`

This command will search in the current directory and all sub directories. All files containing the string ‘test’ will have their path printed to standard output:

./build/build.properties:4:project.name=test
./build/build.xml:12:<target name="sync:test">

Count Strings

If you only want to count the matching lines for each file, then you can use the following command:

$ grep -inc -e 'test' `find -type f` | grep -v :0

This will output:

./build/build.properties:1
./build/build.xml:2

Replace Strings

And finally, if you want to replace all occurrences of the search string with the replacement string:

$ sed -i 's/search/replace/' `find -type f`

Linux Commands

Learn more about these commands:

Advertisement

Written by Federico

July 9, 2008 at 9:05 pm

Posted in Linux, Programming

4 Responses

Subscribe to comments with RSS.

  1. I’d call sed the linux power users’ search and replace tool. A simpler (read: less likely to lead to frustration and/or tears) recursive replace command for linux would be “rpl”.

    isnoop

    July 10, 2008 at 8:27 pm

  2. Running find inside backticks is a recipe for trouble – it can easily overflow the space allowed for a command’s arguments. It will also fail when filenames have spaces.
    This is better:

    find . -type f -print0 | xargs -0 sed -i ‘s/search/replace/’

    I often put the . after find so I know the command will work on BSD/OSX. -print0 will output the files separated by a NUL character so spaces in filenames aren’t ambiguous. xargs will take a stream and split it into pieces small enough to fit in the command buffer. -0 tells xargs to expect a NUL delimited stream. xargs will run sed as few times as possible, better than using -exec in find.

    I hope this helps someone.

    Andrew Kirkpatrick

    July 11, 2008 at 2:01 am

  3. …and if I’m doing anything more subtle/conditional/complex than that, I break out Perl (man File::Find).

    Andrew Kirkpatrick

    July 11, 2008 at 2:04 am

  4. Hi Andrew, thanks for the tip! Very useful. As a matter of fact, I’m doing something similar to count the matching lines for each file:

    find . -type f -print0 | xargs -0 grep -c “keyword” | grep -v :0

    I’ll add this info to the post. Thanks :)

    federico

    July 11, 2008 at 8:17 am


Leave a Reply

Fill in your details below or click an icon to log in:

Gravatar
WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 43 other followers