Замена строки, содержащей специальные символы, на sed - PullRequest
0 голосов
/ 16 сентября 2011

Я просмотрел много сообщений здесь и в других местах на эту тему, но ни одно из предложенных решений, похоже, не работает для меня.Мне нужно заменить строку (которая содержит ошибочный бессмысленный код PHP) на другую строку (содержащую правильный код PHP) во всех файлах в определенной папке.Я понимаю, что единственными символами, которые необходимо экранировать при использовании sed, являются амперсанды, обратные слеши и любые другие символы, используемые в качестве разделителя.

Строка, которую я хочу найти:Строка, которую я хочу заменить на это:

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

Я пробовал множество вариантов, но не могу заставить его работать.Я думаю, что следующая команда должна работать (но не работает).

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];}|' {} \;

Это сводит меня с ума - любая помощь будет принята с благодарностью!

Ответы [ 2 ]

4 голосов
/ 16 сентября 2011

Я наконец нашел правильный синтаксис. Вопреки всем советам, которые я прочитал, мне нужно было избегать знаков доллара и открытых квадратных скобок в ОБА выражениях (но не в квадратных скобках и не в изогнутых скобках). Итак, вот команда, которая наконец-то сработала для меня:

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];/' {} \;

Еще раз спасибо тем, кто ответил.

2 голосов
/ 16 сентября 2011

Я понимаю, что единственные символы, которые нужно экранировать при использовании sed, - это амперсанды, обратная косая черта и любой другой символ, используемый в качестве разделителя

Не верно для поискового выражения. Это регулярное выражение; для буквального сопоставления вам нужно избегать всех специальных выражений регулярных выражений, то есть, по крайней мере, s%\([][^$.\*]\)%\\\1%g (без манжеты - я мог пропустить несколько, и / или ваш sed может отличаться от моего). К счастью, это легко сделать программно, например, с sed - просто будьте осторожны, чтобы не запутаться.

Строка замены является литеральной строкой, за исключением обратных ссылок, поэтому для этой части ваше утверждение верно.

#!/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|" {} \;
...