найти и заменить используя grep внутри jpg файлов - PullRequest
1 голос
/ 29 февраля 2012

Я боролся с проблемой grep, пытаясь отменить серверный хак на моем сервере, но grep, похоже, не в состоянии искать внутри jpg-файлов при запуске в качестве оболочки, но команда grepна своем собственном файле работ в ssh.

это возвращает результаты в порядке: grep -l -R "nastycode" / var / www / vhosts

но когдазапускается как сценарий оболочки, он больше не находит jpgs.

for file in $(grep -l -R "nastycode" /var/www/vhosts)
 do
  sed -e "s/"nastycode"/"nicecode"/ig" $file > /tmp/tempfile.tmp
  mv /tmp/tempfile.tmp $file
  echo "Modified: " $file
 done

В: Может быть, это связано с частью 'for file in'?Q: внутри нашего шаблона поиска "nastycode", можем ли мы искать вещи, которые имеют регулярные выражения, но относиться к ним как к обычным ($, |? Etc)?

заранее спасибо.

Николас

1 Ответ

0 голосов
/ 29 февраля 2012

grep имеет возможность игнорировать специальные символы (-F) до тех пор, пока не будет перевода строки. sed, к сожалению, такой опции не имеет. Если в нем есть специальные символы, они должны быть экранированы. Если у вас много / s, вы можете избежать их, изменив разделитель - s|old|new| или s@old@new@, или какой-либо другой символ, который ваш код не содержит. Что касается остальной части структуры, у меня есть пара комментариев. Во-первых, вы никогда не должны использовать эту for file in command структуру, она будет разбита на пустое пространство; используйте ** (вам может понадобиться сначала включить shopt -s globstar) или find. Далее, GNU sed имеет встроенную опцию -i. Для него также можно указать суффикс резервной копии (например, -i.bak). Поскольку sed изменяется только в том случае, если находит шаблон, на самом деле нет никакой причины использовать grep для ограничения файлов в любом случае.

Собрав все это вместе (после того, как вы вышли из своего регулярного выражения - мы можем помочь с этим тоже, если вам это нужно), вы можете использовать это:

# Globstar
for file in /var/www/vhosts/**; do
    sed -i.bak 's/) || stristr(\$ua/) \&\&false || stristr($ua/ig' $file
done

# find
find /var/www/vhosts -type f -exec sed -i.bak 's/) || stristr(\$ua/) \&\&false || stristr($ua/ig' {} \;

# If you really want the echo notification
find /var/www/vhosts -type f -exec grep -qiF ') || stristr($ua' {} \; -exec sed -i.bak 's/) || stristr(\$ua/) \&\&false || stristr($ua/ig' {} + -printf "Modified %p\n"
...