Linux SED поиск заменить несколько в строке - PullRequest
3 голосов
/ 29 апреля 2011

Мне нужно заменить целую кучу суперглобалистов PHP на клиентском веб-сайте функцией PHP, которую я сделал для очистки суперглобальных объектов от xss-атак.

Вот как может выглядеть оригинальный код:*

echo $_REQUEST['HELLO1'] . ' AND ' . $_REQUEST['HELLO2'];

Мне нужно, чтобы это выглядело так:

echo MYCLASS::myfunction($_REQUEST['HELLO1']) . ' AND ' . MYCLASS::myfunction($_REQUEST['HELLO2']);

Основная проблема, мне нужно выполнить поиск / заменить более 100 файлов!Yikes!

Таким образом, мое решение было таким (в оболочке linux):

sudo sed -i 's/\$_REQUEST[.*\]/MYCLASS::myfunction(&)/g' *.php

Это прекрасно работает, пока только один экземпляр "$ _REQUEST" происходит на строку ...Однако с несколькими экземплярами он облажается и делает это:

echo MYCLASS::myfunction($_REQUEST['HELLO1'] . ' AND ' . $_REQUEST['HELLO2']);

Ответы [ 5 ]

2 голосов
/ 29 апреля 2011

Проблема в том, что .* является жадным и найдет максимально возможное совпадение.Чтобы обойти эту проблему, используйте [^]]* вместо этого, чтобы случайно не взять дополнительный набор квадратных скобок.

sudo sed -i 's/\$_REQUEST\[[^]]*\]/MYCLASS::myfunction(&)/g' *.php

В других диалектах регулярных выражений вы также можете написать .*?, чтобы сделать подстановочный знак не-жадно, но это не работает в sed (по крайней мере, в моей версии, даже с sed -r).

1 голос
/ 29 апреля 2011

sed 's/\$_REQUEST\[[^]]*\]/MYCLASS::myfunction(&)/g'

1 голос
/ 29 апреля 2011

Попробуйте команду sed:

sed -i.bak 's/\$_REQUEST\[\([^]]*\)\]/MYCLASS::myfunction(\1)/g' *.php

или в perl:

perl -pe 's/\$_REQUEST\[([^]]*)\]/MYCLASS::myfunction(\1)/g' file.php
1 голос
/ 29 апреля 2011

В Perl будет работать следующий скрипт, где вы передаете скрипту имя интересующего вас файласкажем, скрипт t.pl и ваш файл file.phpвывести обратно в file.php perl t.pl file.php> file.php выводить в другой файл, чтобы не перезаписывать исходный perl t.pl file.php> another_file.php

#!/usr/bin/perl

$FILE_NAME = $ARGV[0];

open (FILE_NAME) or die ("Could not open FILE_NAME information file: $FILE_NAME \n");
@file_contents = <FILE_NAME>;
close (FILE_NAME);


foreach $line (@file_contents) {
       chomp($line);
       $line =~ s/\$_REQUEST\[.*?\]/MYCLASS\:\:myfunction\($&\)/g;
       print $line." \n";
}

выход;

0 голосов
/ 29 апреля 2011

Это должно сделать это:

sed -i "s/\$_REQUEST\[\([^\x5d]*\)\]/MYCLASS::myfunction(\1)/g" *.php

У меня было много проблем с подбором ], поэтому я получил штраф \x5d.

...