0

I have looked through many posts here and elsewhere on this subject, but none of the solutions offered seem to work for me. I need to replace a string (which contains buggy nonsensical PHP code) with another string (containing the correct PHP code) in all files within a particular folder. I understand that the only characters that need escaping when using sed are ampersands, backslashes, and whichever character is used as the delimiter.

The string I want to search for is:

$arguments = func_get_args();$numargs = func_num_args();for($i=1; $i < $numargs; $i++){$arguments[$i] = $arguments = func_get_args();$arguments[$i];} 

The string I want to replace it with is:

$arguments = func_get_args();$numargs = func_num_args();for($i=1; $i < $numargs; $i++){$arguments[$i] = &$arguments[$i];} 

I have tried numerous variations but cannot get it to work. I think the following command should work (but doesn't).

find /folder/to/search -name Function.php -type f -exec sed -i 's|$arguments = func_get_args();$numargs = func_num_args();for($i=1; $i < $numargs; $i++){$arguments[$i] = $arguments = func_get_args();$arguments[$i];}|$arguments = func_get_args();$numargs = func_num_args();for($i=1; $i < $numargs; $i++){$arguments[$i] = \&$arguments[$i];}|' {} \; 

This is driving me insane - any assitance would be greatly appreciated!

2
  • 1
    Might it be sufficient to just replace the content in the for-loop (which looks like the only difference between the two)? Commented Sep 16, 2011 at 12:40
  • Yes, I probably should have simplified it a bit. When doing a search and replace I normally try to include the whole line so as to avoid false positives but in this case the inner part is specific enough to suffice. Commented Sep 16, 2011 at 13:45

2 Answers 2

4

I finally found the right syntax. Contrary to all the advice I have read, I needed to escape the dollar signs and open square brackets in BOTH expressions (but not the close square brackets nor the curved brackets). So here is the command that finally worked ok for me:

find /folder/to/search -name Function.php -type f -exec sed -i 's/\$arguments\[\$i] = \$arguments = func_get_args();\$arguments\[\$i];/\$arguments\[\$i] = \&\$arguments\[\$i];/' {} \; 

Thanks again to those who replied.

Sign up to request clarification or add additional context in comments.

Comments

2

I understand that the only characters that need escaping when using sed are ampersands, backslashes, and whichever character is used as the delimiter

Not true for the search expression. It is a regular expression; for literal matching, you need to escape all regex specials, i.e. at least s%\([][^$.\*]\)%\\\1%g (off the cuff - I might have missed a few, and/or your sed may differ from mine). Luckily, this is easy to do programmatically, e.g. with sed - just be careful so you don't get confused.

The replacement string is a literal string, except for backreferences, so for that part your statement is true.

#!/bin/sh from=`sed 's%[][^$.\*]%\\\&%'<<'____HERE' $arguments = func_get_args();$numargs = func_num_args();for($i=1; $i < $numargs; $i++){$arguments[$i] = $arguments = func_get_args();$arguments[$i];} ____HERE` to=`cat<<'____THERE' $arguments = func_get_args();$numargs = func_num_args();for($i=1; $i < $numargs; $i++){$arguments[$i] = \&$arguments[$i];} ____THERE` find /folder/to/search -name Function.php -type f -exec sed -i "s|$from|$to|" {} \; 

4 Comments

Thanks - I should have realised the first part was a regex so needed escaping. However, I tried your script and it failed with "line 8: to: command not found" and 4x "expression #1, char 158: Invalid back reference". I also tried this, which did not peform the replacement: find /folder/to/search -name Function.php -type f -exec sed -i 's|\$arguments[\$i] = \$arguments = func_get_args\(\);\$arguments[\$i];|$arguments[$i] = \&$arguments[$i];|' {} \;
it should be to=`cat ... (no spaces around the =. Good luck!
Thanks, that fixed the first error, but I still get char 158: Invalid back reference, and the replace is not performed.
Sorry, should have tested more thoroughly before posting. I have edited the code but it might still require tweaking; I did my testing on OSX, where sed works slightly differently from e.g. Linux.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.