0

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

TecBrat
  • 173
  • 10

2 Answers2

2

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>";?'

cjc
  • 24,533
  • 2
  • 49
  • 69
  • 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 for Make a backup! Make a backup! – TecBrat Apr 11 '12 at 01:32
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\
"$my_return_var="
'
glenn jackman
  • 4,320
  • 16
  • 19
  • 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
  • I actually put it all on one line, so I'm not sure why I got the extra newline, but I'm not worried about it. I already implemented it and the PHP parses correctly anyway. – TecBrat Apr 10 '12 at 17:25