Find & Replace across multiple files in linux

Here’s the post on my new blog – http://rushi.vishavadia.com/blog/find-replace-across-multiple-files-in-linux/
Below is an older version of the post:

I was trying to find a solution todo a find & replace across multiple files which was purely command line based. There are plenty of scripts out there which will accomplish this but I needed a single line command. After some google searches and some experimentation I came up with this snippet.

find . -name "*.php" -print | xargs sed -i 's/foo/bar/g'

It looks a bit complicated but its quite simple. There are three components to the command:

  1. find . -name "*.php" -print – Find all files (recursively) which has “.php” in the file and print them out. This will give you output like this:
    ./file.php
    ./includes/test.php
    ./classes/class.php
  2. xargs– This command is used when you want to pass a lot of arguments to one command. xargs will combine the single line output of find and run commands with multiple
    arguments, multiple times if necessary to avoid the max chars per line limit. In this case we combine xargs with sed
  3. sed -i 's/foo/bar/g' – aka Stream Editor is a tool which should be in every sys admin’s toolkit.  In this case every occurence of “foor” is replaced by “bar” in all the files found using the “find” command. Sed simply parses input and applies certain text transformations to it. There’s a lot to say about sed, you can find more at this tutorial.

This pretty much covers the core of the find & replace command. You could also open up a particular folder in an IDE and use it’s find and replace feature. But find + sed is quite fast and powerful.

Resources:

58 comments

  1. Nice how to!
    This really saved my ass! Keep it up.

    C

  2. […] simple, and preferably a single line command. After a lot of Google-ing, I ended up finding this post, which does a great job of explaining how to do this in linux. The basic command is: find . -name […]

  3. devGOD · ·

    thanks this helped me out a lot.

  4. suganya · ·

    Awesome!! with a single command and it satisfies find and to replace a text.

  5. Aaron · ·

    I miss linux :( I am stuck on a windows vista machine at work. Does anyone know how to do this on Windows?

    1. gnu win utils – I install the lot on my machine. They go to %programfiles%/gnu/bin
      I then alter my path to include that in it.
      That gives me sed, grep, scp, ftp, ssh etc etc etc
      cygwin is cool but ends up putting an emulation type layer – gnu win utils are all precompiled for windows.

      1. PS Pad

  6. Aaron you can install Cygwin – http://www.cygwin.com/ – if you like Linux and the command line, you will like Cygwin.

  7. when i do this:
    /www/htdocs/html/article> find . -name “*.html” -print | xargs sed -i ‘s/2008/2009/g’
    I get the error:
    sed: 1: “./article/study_finds_c …”: invalid command code .

    Any idea what this means??? thanks in advance!!

  8. @ lm. The error probably lies in the text delimiter that you chose for sed.

    Sed gets confused when you use a “/” in the field that you want to replace letters. Try using something like :
    sed -i ‘s_2008_2009_g’ or sed -i ‘s:2008:2009:g’. That should help solve your problem.

    1. I still get the same error even after replacing it with “:” or “_” ..

      find . -name “*.gnu” -print | xargs sed -i ‘s:bottom:top:g’
      sed: 1: “./1LDAWC.gnu”: invalid command code .

      1. Awesome thanks a lot :-)

  9. António PT · ·

    Thanks a lot!

  10. Danny · ·

    you save my life.

  11. thanks!

  12. manopkgt · ·

    Thank you .
    nice command .

  13. thanks for posting this, finding this was tougher than i thought, spent 45 minutes. have a good one!

  14. […] opción de Komodo Edit de buscar y reemplazar en todos archivos del proyecto. Para eso encontré en este blog, la siguiente solución en una sola línea de comando que […]

  15. […] Find & Replace across multiple files in linux « Rushi’s Ramblings a few seconds ago from web […]

  16. You can use also this:

    ~$ find . -name "*.php" -exec sed -i 's/foo/bar/g' {} \; 
    

    find is a powerful command! :)

    My two cents.

    Bye

  17. quesder · ·

    What if I want to replace the path string “/d1/d2” to “/d1/d2-new/ “?

    Does the escape char ‘\’ work here?

  18. Playriver · ·

    Mind Formal,run research critical dress what transfer arrange before plastic dress appear heat of secretary long great guide finger game unless commit slightly county happen working across officer judge movement rise run bloody discipline respond approach vote machine intention potential my liability pub why early grant of charge elsewhere child accident properly illustrate reform tool recently afterwards air encourage suppose mention need good source benefit problem compare artist money just clean transfer general therefore visitor crisis writer ourselves lead all him proposal art communication mass arrive sky successful tree start life

    1. spam

  19. Ben · ·

    What if i want to get sub directories within the directory im running the command in?
    Getting
    xargs: unmatched single quote; by default quotes are special to xargs unless you use the -0 option

    Thanks!

  20. kun's · ·

    I am getting following error, how can i solve?
    sed -i “s/asdjfl;askdjfl;ajkdf/sdfalsdjfaskl;d/g” *.c
    sed: invalid option —

    Thanks in advance..

    1. kun’s — i don’t seem to get that error. What version of sed are you using ?

      Just make sure the quotes and dashes are the correct ASCII version and you aren’t copy/pasting the command from anywhere. Word processing docs like MS Word will use a different style of quotes and dashes.

  21. […] Jeder kennt das, eine Bezeichnung hat sich geändert, ein Tippfehler muss überall gefunden werden, ein bestimmter Ausdruck ist grundsätzlich falsch, immer wieder kommt es vor, dass man ein und denselben Ausdruck in ganz vielen Dateien ersetzen muss. Einfach geht das natürlich mit einem leistungsfähigen Texteditor, oder einer IDE. Manchmal hat man auf dem Server aber nicht viel mehr als eine Shell. Wenn man das Glück hat und find, xargs und sed sind installiert ist das ganze trotzdem sehr einfach. Eine Zeile reicht: find . -name "*.java" -print | xargs sed -i 's/alt/neu/g' und das ganze ohne Installation. Quelle: https://rushi.wordpress.com/2008/08/05/find-replace-across-multiple-files-in-linux/ […]

  22. One of the most useful one-liners ever !
    I can’t believe I used to write whole perl scripts to do that before.
    Thx.

  23. vikram · ·

    Thanks for the command

  24. Great! Just what I needed — sed’s ‘-i’ (work in place) option!

  25. Mike Bender · ·

    I ran this command and it deleted half the files in the search. Thanks!

  26. Thanks for the post, it saved my time…

  27. Vishnu · ·

    this command breaks when there is a space in the filename
    pls help
    thanks.

  28. Thank you for posting code!

  29. Shiva · ·

    same as Vishnu: it breaks when there are spaces in the folder names

  30. Grateful · ·

    Thanks, this rocks!

  31. Very useful. Thank you. I have done a little reading on this.
    As some have discovered, allowing spaces in file and directory names is almost always a mistake.
    It could be made clearer that the s/ part of the command is the bit where the user chooses which character is going to signify the end of the searched-for text and the beginning of the replacement text. You can’t use a / in either of the strings. (If you do, sed thinks you’re sending too many parameters.) If you use s% instead of s/ you can use / but not % in the two strings.

  32. The rrep program lets you replace strings in multiple files and also recursively in directories. It also supports regular expressions. The usage is similar to grep.
    Available in Debian, Ubuntu and at http://sourceforge.net/projects/rrep/

  33. SirDerp · ·

    I ran this command and my computer uninstalled everything even solitaire

    1. Awesome – glad it was helpful – you are halfway to getting a proper operating system installed

  34. If you’re trying to run this on OS/X, and you get a “bad command code” error:

    sed -i requires an extra blankquotes arg after the switch and before the pattern arg:

    find . -name “*.php” -print | xargs sed -i “” ‘s/foo/bar/g’

    See:
    http://www.markhneedham.com/blog/2011/01/14/sed-sed-1-invalid-command-code-r-on-mac-os-x/

  35. This saved many asses today, seriously

  36. fixing my error: ‘Privacy and Cooking Policy’ with ‘Privacy and Cookie Policy’

    Lovely stuff. Thanks

  37. Vivek · ·

    For mac users:

    find . -name “*.php” -print | xargs sed -i “” ‘s/foo/bar/g’

  38. Just a little info when trying to find/replace on ALL files. Performing:

    find . | xargs sed -i ‘s/foo/bar/g’

    you will get:

    sed: couldn’t edit .: not a regular file

    You need to exclude . and directories if you want to find and replace on “everything” and not just *.php. A more stable version to find/replace in all files:

    find . -type f -not -name “.*” -print | xargs sed -i ‘s/foo/bar/g’

  39. vyctorlm · ·

    Thanks, a lot!!

  40. Thanks. This came in handy!

  41. Vinnie · ·

    For Find & Replace in Multiple Word file you can use the tools

    http://lantechsoft.com/advance-find-replace.html

  42. Thanks. Worked like a charm.

  43. Amit Durge · ·

    I want to remove the weird / special characters from the bunch of text files. Here i used the following command to remove the weird characters but it gives me the error.

    Command :

    1) grep -lri -e ââ¬Å temp.txt | xargs sed -i ‘ s_ââ¬Å_”_g’

    2) grep -lri -e ââ¬Å temp.txt | xargs sed -i ‘ s/ââ¬Å/”/g’

    3) grep -lri -e ââ¬Å temp.txt | xargs perl -piew ‘ s_ââ¬Å_”_g’

    4) grep -lri -e ââ¬Å temp.txt | xargs perl -piew ‘ s/ââ¬Å/”/g’

    Here I want to replace ââ¬Å this character with ” quote.

    These are the some Weird characters that I want to remove from the text files :

    – , — , ; , : , ! , ¡ , ¿ , · , ‚ , ‹ , › , » , @ , / , \[ , \]\\ ,
    \^ , \+ , \ , \$ , \s , & , # , % , †, ‡ , ` , ´ , ¯ , ˘ , ¨ , § , ¶ ,
    © , ® , ℠, ° , º , ∂ , ∆ , ∠, ∑ , ± , = , ≠, ¬ , \ , , ~ ,
    ∫ , € , ª , à , â , Ã… , ä , Æ , Ç , è , ë , ï¬ , fl , Æ’ , í , ì ,
    î , ï , ó , ò , ô , ö , õ , ø , œ , ß
    and so on.

    Please help me on this & Also suggest the command to remove the bunch of weird characters.

    1. sed ‘s/’`echo “\— `'””‘

      Basically the command is
      sed -e ‘s/’$(echo “octal – value”)’/replacement_words/g’

      grepping the web also reveals for stripping chars, adding a replace in there might work.:
      perl -i.bak -pe ‘s/[^[:ascii:]]//g’
      or
      sed -i ‘s/[^[:print:]]//’ FILENAME

      lastly – there is an older command called unix2dos, that may do what you require, stripping out not ascii stuff but it wont do the replace.

  44. ipsita · ·

    cooolio…..!!!!!! :) it worked wonders for me…
    Thanx..:)

  45. You have a typo. It’s ‘foo’ not ‘foor’

  46. Oufie · ·

    That’s great .. It helped me save a great deal time :)

    Thank you!