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.

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

"$my_return_var="

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

share|improve this question

2 Answers 2

up vote 2 down vote accepted

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\
"$my_return_var="
'
share|improve this answer
    
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 '12 at 14:51
    
@TecBrat, sorry, forgot to put the pattern in the sed command. Plus you have to do some quoting tricks. Answer updated. –  glenn jackman Apr 10 '12 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 '12 at 15:10
    
@TecBrat, put the closing single quote on the previous line to get rid of that extra newline. –  glenn jackman Apr 10 '12 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 '12 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>";?'

share|improve this answer
    
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 '12 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 '12 at 13:52
1  
Thanks. Looks like @glenn's is working for me. –  TecBrat Apr 10 '12 at 13:53
    
+1 for Make a backup! Make a backup! –  TecBrat Apr 11 '12 at 1:32

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.