2012-04-04 6 views
0

Моей ситуации:Linux GREP/SED [xargs] найти шаблон и номер строки в файлах и удалить с SED

  1. У меня есть очень длинная текстовая строка, содержащая специальные символы, что происходит на длинную линии в различных файлах. Файлы, содержащие строку, находятся в файловой системе (Linux). Строка может быть в разных номерах строк в файлах, где она встречается, но встречается один раз для каждого файла. Строка, однако, содержит определенный шаблон, который я могу использовать для идентификации всей строки.

  2. Я знаю, как найти имена файлов, содержащих строку, используя ключ «префикс» строки, используя GREP -lir mystringprefix/path.

  3. Я знаю, как определить номер строки строки в файле, используя GREP и SED, используя grep -n "prefix" file.name | sed -n "s/^ ([0-9] ) [:]./\ 1/p ".

  4. Я знаю, как использовать SED для удаления на месте строки в файле, содержащей интересующую строку, с помощью sed -i xd/path/file (x - номер строки, который нужно удалить).

Мой вопрос, как я могу поставить все это вместе, чтобы определить, какие файлы содержат шаблон, передать имя 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 не выжить.

+0

Я не могу найти переключатель командной строки SED на страницах man. Что делает этот переключатель? (ваш ответ также предполагает, что я мог бы быть подан с помощью GREP -lirZ для принудительного использования \ 0). – GWild

+1

@GWild: '-ibk' подобен' -i bk', он указывает суффикс, который будет использоваться при создании файлов резервных копий при изменении. Я полагаю, что использование '-i.bak' сделало бы это более очевидным – Sorpigal

+0

К сожалению, ни один пример не работает в моем случае. Я продолжаю получать ошибку SED «Не могу найти метку для перехода», и она ссылается на мою строку шаблона. Я ценю попытку помощи. По какой-то причине SED задыхается от простого текста.Идет к тому, почему я изначально хотел номер строки и смог ее передать. GREP находит строку без проблем. – GWild

0

Узор: с учетом регистра.

grep -Zlr 'mystringprefix' /path/ | xargs -0 sed -i '/mystringprefix/d' 
Смежные вопросы