grep: показать все выходные данные, но выделить совпадения поиска

40

В bash, если я хочу выполнить команду и отображать только выходные строки, которые соответствуют определенному шаблону, я могу передать его grep, например,

файл тестового файла

hello
there
my
friends

команда

$ cat testfile | grep 'hello'
hello #this will be highlightd

это выделит совпадение поиска и отобразит всю строку, на которую оно попадает. Я могу использовать -Aи -Bдля отображения строк до и после этой строки. Мой вопрос заключается в том, можно ли выполнить команду и отобразить все выходные данные в обычном режиме, но выделять результаты поиска, как это делает grep? так что мой выход будет

hello #highlighted
there
my
friends
Ewok
источник
3
См. Убедить grep, чтобы вывести все строки, а не только строки с совпадениями (U & L) или Colorized grep - просмотр всего файла с выделенными совпадениями (переполнение стека) для лучших ответов.
G-Man говорит: «Восстановите Монику»

Ответы:

38

Чтобы использовать Color GREP для выделения только совпадающих рисунков, но не для изменения выходных данных:

grep --color=always -e "^" -e "hello" testfile

Первый шаблон будет соответствовать всем строкам (будут напечатаны все строки), а второй шаблон (и любые последующие шаблоны) приведет к тому, что соответствующий текст будет выделен цветом.

Поскольку первый шаблон соответствует всем строкам, но не соответствует печатному символу, он не добавляет никакой цветовой подсветки, поэтому он не конкурирует / не мешает удобочитаемости выделенного текста.

bot779
источник
Работает с kubectl kubectl apply -k . | grep --color=always -e "^" -e "configured"в Zsh
Майкл Коул
Для использования в Bash: highlight () {grep --color = всегда -e "^" -e $ *; }
Джон
Это работает и во FreeBSD, вам просто нужно поменять местами первый и второй шаблон ( "^"должен быть второй).
Мариан Черны
25

Добавьте опцию -zк вашей команде GNU grep:

cat testfile | grep --color=always -z 'hello'

или короче

grep --color=always -z 'hello' testfile
Кир
источник
3
Это очень грубый взлом. Это приводит к тому, что весь файл рассматривается как одна строка. Таким образом, (1) , если файл очень большой, может быть возможность запуска из памяти, и (2) , если файл не содержит шаблон вообще , то ничего не будет выводиться.
G-Man говорит: «Восстановите Монику»
На какой версии grep это поддерживается? На grep 2.5.4 -z не доступен ...
Alex
@Alex: я использовал GNU grep версии 2.6.3.
Сайрус
2
@ G-Man: больше ресурсосбережения:grep --color "hello\|$" file
Cyrus
@Cyrus: Да, это лучший ответ. К сожалению, он по сути эквивалентен ответу bot779 на этот вопрос и почти идентичен принятым ответам ( 1 и 2 ) на вопросы, с которыми я связан.
G-Man говорит: «Восстановите Монику»
4

Как и в предыдущем ответе, вы можете перехватить все $концы строк:

cat testfile | grep --color -E "hello|$"

-E(или --extended-regexp) означает, что специальные символы должны быть экранированы \. При его использовании| будет рассматриваться как условие регулярного выражения "ИЛИ".

Grep |$ также перехватит и напечатает все строки, которые имеют конец, но поскольку $ является скрытым символом, его нельзя выделить.

Обновить:

Если вы хотите распечатать все выходные данные, а также вернуть код завершения , независимо от того, найдено совпадение или нет, вы можете использовать команду perl:

cat testfile | \
perl -pe 'BEGIN {$status=1} END {exit $status} $status=0 if /hello/;'

Если вы предпочитаете sed - вот пример, как выделить все совпадения + код возврата, если совпадений не найдено: https://askubuntu.com/a/1200851/670392

Ноам Манос
источник
2

Этот работает с GNU grep, а также с grep во FreeBSD:

grep --color=always 'hello\|$'

Соответствует тексту «привет» или ( \|) непечатаемой пустой строке в конце каждой строки ($ ). Вот почему каждая строка печатается, но выделяется только «привет».

Скорее всего, вы уже --color=autoнастроили в своей оболочке. Тогда вам, скорее всего, не нужно указывать --color=always:

grep 'hello\|$'

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

egrep 'hello|$'
Мариан Черны
источник
Это не отвечает, как отобразить все строки ввода.
Крис Пейдж
@ChrisPage Я бы сказал, что так и есть: вот почему каждая строка печатается, но выделяется только «привет».
Мариан Черны
0

Добавление к верхнему ответу выше. Функция highlight {}, упомянутая в комментариях, работает только тогда, когда в нее передаются данные. Следующий псевдоним, хотя и не идеальный, более полезен:

alias greph="grep --color=always -e^ -e"

Это работает с такими командами, как:

greph foo bar.txt

cat bar.txt | greph foo
rpmohn
источник