Intereting Posts
Отображение пользователя в пользователя файловой системы при несовпадении UID? Команда высокого уровня для запроса нескольких ветвей snmp в одном сеансе tcp-сессии? openwrt firewall – блокировать набор IP-адресов из интернет-доступа Невозможно построить QTAV для cubieboard2 на кубине postfix фильтрует входящие письма на основе «mail from» и «rcpt to» как напечатать только часть каждой строки, которая помечается определенным символом оптимизировать команду с помощью or или pipe для анализа вывода ifconfig Bash while loop читает из списка путей, разделенных двоеточиями, используя IFS Правильное понимание прав для cp Почему mknod требует привилегии root? Enigmail Thunderbird pinentry запрашивает все пароли ко всем секретным ключам Почему это временно выглядит так, что предел передачи команды pv больше не применяется, когда я выхожу из приостановки в ram? Как получить полный снимок экрана, который выходит из экрана? Как сделать файлы неизменяемыми и неуязвимыми без `chattr`? Форматирование переменной с плавающей запятой в инструкции SED

строка grep, где следующая строка не содержит строки

Я хочу искать все файлы внутри каталога и его подкаталоги для строк, содержащих определенную строку, но я хочу исключить те результаты, которые содержат определенную строку в строке сразу после нее.

Например, это:

foo1 searchString bar foo1 excludeString bar foo2 searchString bar something else foo3 searchString bar foo3 excludeString bar foo4 searchString bar 

должен вернуть это:

 foo2 searchString bar foo3 searchString bar foo4 searchString bar 

Я знаю, что -A печатает несколько строк и что -v исключает результаты. Но мой текущий подход grep -r -A 1 "searchString" | grep -v "excludeString" grep -r -A 1 "searchString" | grep -v "excludeString" явно не может работать.

Есть ли способ сказать второй grep, что он также должен удалить предыдущую строку, если найдет совпадение? Или каким-то другим способом, как я мог бы это достичь?

Производительность не является моей главной задачей; Было бы неплохо, если команда относительно легко запомнить.

Вы можете использовать следующие параметры: grep :

 $ pcregrep -M '(searchString.*\n)(?!.*excludeString)' file foo2 searchString bar foo3 searchString bar foo4 searchString bar 

Он ищет searchString за которым следует любой символ . , повторяется ноль или более раз * , а затем новая строка \n только если нет ( ?! ) шаблона .*excludeString рядом с ним. Параметр -M присутствует, чтобы соответствовать нескольким линиям.

С sed :

 sed '/searchString/!d;$!N;/\n.*excludeString/!P;D' infile 

Как это работает:

  • /searchString/!d удаляет строку, если она не соответствует searchString и читается в новой строке, снова запуская командный цикл (т.е. оставшиеся команды больше не выполняются)
  • если строка соответствует searchString , sed выполняет $!N;/\n.*excludeString/!P;D – см. ЗДЕСЬ, как это работает; разница в том, что здесь он ищет шаблон excludeString после excludeString \n ewline, так что строка, соответствующая как searchString и excludeString , все еще печатается, если за ней не следует строка, соответствующая excludeString ; если не было строки, соответствующей как searchString и excludeString (т. е. известный ввод), вы можете удалить часть \n.* и запустить:
    sed '/searchString/!d;$!N;/excludeString/!P;D' infile