Linux GREP / SED [xargs] находит шаблон и номер строки в файлах и удаляет с помощью SED

Моя ситуация такова:

I have a very long text string, containing special characters, which occurs on a long line in various files. Files containing the string are throughout the file system (Linux). The string may be on various line numbers in the files where it occurs, but occurs once per file. The string, however, contains a specific pattern which I can key on for identification of the entire string.

I know how to find the names of files containing the string by keying on the 'prefix' of the string using GREP -lir mystringprefix /path.

I know how to determine the line number of the string in the file using GREP and SED using grep -n "prefix" file.name | sed -n “s/^([0-9])[:]./\1/p”.

I know how to use SED to delete in place the line in the file containing the string of interest using sed -i xd /path/file (x is the line number to be deleted).

Мой вопрос: как я могу собрать все это вместе, чтобы определить, какие файлы содержат шаблон, передать имя в GREP, чтобы определить номер строки в файле, а затем передать и имя, и номер строки в SED, чтобы удалить строку?

Мне нужно сделать это таким образом, чтобы начать в определенном месте в файловой системе, а затем выполнить его поиск / удаление рекурсивно.

Спасибо.

Ответы на вопрос(2)

Решение Вопроса

Довольно просто:

for file in "$(grep -lir 'prefix' /path/)" ; do
    sed -ibk -e '/prefix/d' "$file"
done

Где мы предполагаем, чтоgrep -lir prefix /path/ возвращает список имен файлов, разделенных символом новой строки, и что ваш префиксный шаблон также является чем-тоsed пойму.

Мне не нужно определять номер строки здесь, потому что я говорюsed чтобы найти линии, которые соответствуютprefix и удалите их напрямую.for file in "$(grep ...)" Конструкция, однако, несколько небезопасна, потому что злоумышленник может создать имя файла, которое заставит его сделать то, чего вы не ожидаете. Было бы лучше сказать:

grep -lir 'prefix' /path/ --null | while IFS= read -r -d '' file ; do
    sed -ibk -e '/prefix/d' "$file"
done

Хотя учтите, что переменные присваиваются в телеwhile петля не переживет этого.

 GWild05 апр. 2012 г., 02:28
К сожалению, ни один пример не работает в моем случае. Я получаю ошибку SED "Не могу найти ярлык для перехода" и это ссылается на мою строку шаблона. Я ценю попытку помощи. По какой-то причине SED задыхается от простого текста. Идет к тому, почему я изначально хотел номер строки и чтобы можно было ее пропустить. GREP находит строку без проблем.
 GWild04 апр. 2012 г., 14:05
Я не могу найти переключатель командной строки SED для k на страницах man. Что делает этот переключатель? (ваш ответ также говорит о том, что меня можно использовать с помощью GREP -lirZ для принудительного применения \ 0).
 04 апр. 2012 г., 14:28
@GWild:-ibk как-i bkОн указывает суффикс, который будет использоваться при создании файлов резервных копий при изменении. Я полагаю, используя-i.bak сделал бы это более очевидным
 17 апр. 2012 г., 01:49
Второе утверждение у меня сработало, первое фактически не меняло файлы, просто перечисляло их
 GWild05 апр. 2012 г., 02:38
Я редактировал мой комментарий выше, чем отведенное время. Извиняюсь. Я использовал вторую версию, и она, похоже, сработала (не на моей тестовой системе дома, а в «рабочей»). Спасибо за помощь.

Шаблонcase-sensitive.

grep -Zlr 'mystringprefix' /path/ | xargs -0 sed -i '/mystringprefix/d'

Ваш ответ на вопрос