it-swarm-ru.tech

Показать все файлы до матча

grep --before-context 5 показывает 5 строк перед матчем.

Я хочу показать все перед матчем.
Делая grep --before-context 99999999 будет работать, но это не очень ... профессионально.

Как показать все файлы до матча?

78
Nicolas Raoul

Sed лучше для этого.

Просто делать:

sed '/PATTERN/q' FILE

Это работает так:

Для каждой строки мы смотрим, соответствует ли она /PATTERN:

  • если да, мы распечатаем его и выйдем
  • в противном случае мы печатаем это

Это наиболее эффективное решение, потому что, как только он видит PATTERN, он выходит. Без q sed продолжит читать остальную часть файла и ничего с этим не сделает. Для больших файлов это может иметь значение.

Этот трюк также можно использовать для эмуляции head:

sed 10q FILE
104
Mikel

sed может заменить большую часть функциональности grep.

sed -n '1,/<pattern>/ p' <file>

Это означает печать с первой строки до совпадения шаблона.

Несколько примеров из диапазона

sed -n '/<pattern>/,$ p' <file> # from pattern to end of file
sed -n '/<pattern1>/,/<pattern2>/ p' <file> # from pattern1 to pattern2
39
forcefsck

распечатать до и включая матч:

awk '{print} /pattern/ {exit}' filename
sed '/pattern/q' filename

распечатать до НО НЕ включая матч:

awk '/pattern/ {exit} {print}' filename
sed '/pattern/Q' filename
39
glenn jackman

Для людей, которые предпочитают запоминать только основные инструменты в повседневной работе и готовы принять менее изящные и менее эффективные решения:

head -n $(grep -n pattern filename | cut -d: -f1) filename

Если эта команда предназначена для скрипта, я буду искать более элегантные (и, возможно, эффективные) решения. Если это одноразовая команда или сценарий выброса, мне все равно.

1
lesmana

Добавление к ответу Микеля выше ...


Чтобы напечатать все строки до (но не включая ) первой строки в FILE, содержащей PATTERN, попробуйте:

  • sed '/.*PATTERN.*/{s///;q;}' FILE

Это соответствует всей строке, содержащей шаблон, заменяет ее пустой строкой, а затем завершает работу без обработки остальной части файла.


Пост-скрипт:

Самый простой/понятный способ предотвратить вывод дополнительной строки в конце (без использования другого инструмента) - это снова запустить sed и удалить новую последнюю строку:

sed '/.*PATTERN.*/{s///;q;}' FILE | sed '$d'

... и так как мы сейчас удаляем эту строку в любом случае, наша предыдущая работа избыточна, и мы можем упростить до:

sed '/PATTERN/q' FILE | sed '$d'
1
Jim Grisham

Следующие чистые методы GNU grep) неэффективны.

Ищите все до первого первого экземпляра строки " foo " в строка файла , используя три greps:

grep -m 1 -B $(grep -n -m 1 foo bar | grep -o '^[0-9]*') foo bar

Соответствует последнему экземпляру " foo ":

grep -oPz "(?s)[^\n]*${s}.*?\n.*?foo.*?\n" bar

Примечание: подробности о последнем grep можно найти в: необходимо регулярное выражение (grep) для многострочного поиска .

1
agc

Вы также можете использовать один из следующих

tac ./test | grep -B $(cat ./test | wc -l) -m 1 'pattern'|tac 

или

tac ./test |head -n $(tac ./test | grep -n 'pattern' | cut -d: -f1 | head -n 1)|tac

или

tac ./test |sed ':a;N;$!ba;s/\n/'"pattern"'/g' | sed 's/'"patternpattern"'/\n/g'|head -n 1|sed 's/'"pattern"'/\n/g'|tac

Первый вариант очень похож на предложенный ОП, только он обеспечивает отображение достаточного количества строк перед контекстом путем подсчета строк в файле.

Вторая опция ищет номер строки первого совпадения (вы также можете изменить это, изменив внутреннюю "голову") и затем использует заголовок для этого номера

Последний параметр заменяет все новые строки соответствием, а затем заменяет два соседних совпадения новой строкой. Результатом этого является строка для каждого блока текста между двумя совпадениями. После этого он использует 'head', чтобы выбрать первую строку (отрывать блок текста до первого совпадения), и затем переводит каждое совпадение в новую строку. эта опция работает, только если файл имеет следующий формат

pattern
texttexttext
texttexttext texttexttext
texttexttexttexttexttexttexttexttext
pattern
texttexttext
pattern 
texttexttext
texttexttexttexttexttexttexttexttext

и так далее

0
user122778