I have a certain php code comment that appears in about 75 files across several users. This command succsessfully locates it. (I didn't bother looking for the double slashes because I wasn't sure about escaping them and they really don't matter for this match.)

grep -l -r "calls the myfunc() function" /home/*/public_html   

After I find it, I need to add a line break and some more php code like

if($my_return_var===false){echo "<b>THERE WAS AN ERROR</b>";}

I also need to do similar, like

grep -l -r "include('path/to/my/file.php')" /home/*/public_html   

and then insert BEFORE it


Searching Google, I found that grep piped to sed is probably the way to go, but I'm not sure of the syntax.

Can anyone help? By the way, this q/a is probably close, but still a little over my head. How to replace a text string in multiple files in Linux

2 Answers 2


sed can do inserts and appends when it sees a pattern:

grep -l -r "calls the myfunc() function" /home/*/public_html |
xargs sed -i '/calls the myfunc() function/a\
if($my_return_var===false){echo "<b>THERE WAS AN ERROR</b>";}

grep -l -r "include('path/to/my/file.php')" /home/*/public_html |
xargs sed -i "/include('path\\/to\\/my\\/file.php')"'/i\
  • I clicked on accept because your first one worked. I am having difficulty with the second one. I'll post details in a sec. @glenn
    – TecBrat
    Apr 10, 2012 at 14:51
  • @TecBrat, sorry, forgot to put the pattern in the sed command. Plus you have to do some quoting tricks. Answer updated. Apr 10, 2012 at 14:58
  • Thanks! I started to say I might never have figured it out, but that's stretching it a bit, but you sure saved me a lot of time. The second one adds a line break, right after the inserted text, that I didn't expect, but I think I can live with it. Can we omit that? (the line break before the append on the first one was desireable, so I'll leave that alone.)
    – TecBrat
    Apr 10, 2012 at 15:10
  • @TecBrat, put the closing single quote on the previous line to get rid of that extra newline. Apr 10, 2012 at 15:59
  • By the way, I just went from testing to the real thing and it went very smoothly. If I could upvote a second time, I would. :-)
    – TecBrat
    Apr 10, 2012 at 17:14

First thing: make a backup!

Second thing: make a backup!

Since I know perl much better than python, I'd use the perl solution.

Remember that "\n" is a newline in perl, so, something like:

grep -l -r "calls the myfunc() function" /home/*/public_html |xargs perl -pi -e 's/(calls the myfunc() function;)/$1\n if($my_return_var===false){echo "<b>THERE WAS AN ERROR</b>";}/'

I have obviously not tested this, and that's a brute force way to do it (and assumes a bunch of things, e.g., the grep doesn't return filenames with spaces in them and so on). If your search/replace patterns contain "/", you can use an alternative delimiter to your pattern, e.g., s?(calls the myfunc() function;)?$1\n if($my_return_var===false){echo "<b>THERE WAS AN ERROR</b>";?'

  • for the second half, do I have to do escapes, like this: ...|xargs perl -pi -e 's/(include(\'path/to/my/file.php\');)/\$my_return_var=$1;}/'
    – TecBrat
    Apr 10, 2012 at 13:18
  • Oh, I probably needed more escapes for the parens in the patterns. Realistically, I probably wouldn't try to do a one-liner. I'd write a perl script for this.
    – cjc
    Apr 10, 2012 at 13:52
  • +1 for Make a backup! Make a backup!
    – TecBrat
    Apr 11, 2012 at 1:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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