Убедить grep выводить все строки, а не только те, которые содержат совпадения

Убедить grep выводить все строки, а не только те, которые содержат совпадения

Допустим, у меня есть следующий файл:

$ cat test

test line 1
test line 2
line without the search word
another line without it
test line 3 with two test words
test line 4

По умолчанию grepвозвращает каждую строку, содержащую поисковый запрос:

$ grep test test

test line 1
test line 2
test line 3 with two test words
test line 4

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

Мой текущий ужасный хак для достижения этой цели (по крайней мере для файлов, в которых нет более 10000 последовательных строк без совпадений) выглядит так:

$ grep -B 9999 -A 9999 test test

Скриншот двух команд

Если grepэто не удается, есть ли другой инструмент командной строки, который предлагает ту же функциональность? Я возился сack, но, похоже, и для этого нет возможности.

решение1

grep --color -E "test|$" yourfile

То, что мы здесь делаем, это сопоставление с шаблоном $, а тестовый шаблон, очевидно, $не имеет ничего для раскрашивания, поэтому только тестовый шаблон получает цвет. -EПросто включается расширенное сопоставление регулярных выражений.

Вы можете легко создать из этого функцию, например, такую:

highlight () { grep --color -E "$1|$" "${@:1}" ; }

решение2

ack --passthru --color string file

для Ubuntu и Debian используйте ack-grep вместо ack

ack-grep --passthru --color string file

решение3

Другой способ сделать этоправильноипортативнос grep(помимо использования двух регулярных выражений с чередованием, как в принятом ответе) осуществляется через шаблон null (и соответственно строку null).
Он должен работать одинаково хорошо с обоими -Eи -Fпереключателями, поскольку,по стандарту:

-E
    Match using extended regular expressions. 
    [...] A null ERE shall match every line.

и

-F
    Match using fixed strings.
    [...] A null string shall match every line.

Так что это просто вопрос бега

grep -E -e '' -e 'pattern' infile

и соответственно

grep -F -e '' -e 'string' infile

решение4

ripgrep

Используйте ripgrepс его --passthruпараметром:

rg --passthru pattern file.txt

Это один изсамые быстрые инструменты поиска, так как он построен на основеРегулярный движок Rustкоторый использует конечные автоматы, SIMD и агрессивные литеральные оптимизации, чтобы сделать поиск очень быстрым.

--passthru- Распечатать как совпадающие, так и несовпадающие строки.

Другой способ добиться похожего эффекта — изменить шаблон так, чтобы он соответствовал пустой строке. Например, если вы ищете с помощью , rg fooто использование rg "^|foo"вместо этого выведет каждую строку в каждом искомом файле, но будут выделены только вхождения foo. Этот флаг включает то же поведение без необходимости изменять шаблон.

Связанный контент