grep: как раскрасить 2 ключевых слова?

12

Я знаю, как выполнить grep 2 ключевых слов, используя 1 команду, но мне удается только покрасить одно из них в выводе. Вот моя команда:

grep 'keyword1' file.log | grep 'keyword2'

Только keyword2подсвечивается. Как сделать keyword1выделение одновременно?

Raptor
источник

Ответы:

15

Команда grepпринимает --color=alwaysопцию, поэтому вы можете использовать

grep 'keyword1' file.log --color=always | grep 'keyword2'

Как указывает gertvdijk , эта команда может быть неэффективной, но она будет искать все строки, содержащие как ключевое слово1, так и ключевое слово2. Если вы хотите выделить их разными цветами, вы можете использовать

grep 'keyword1' file.log --color=always | GREP_COLORS="mt=01;34" grep --color=always 'keyword2'

который выделит ключевое слово 2 синим цветом. Эта mtчасть означает, что grepбудет выделен соответствующий текст с использованием этого кода CSI , и 01;34означает «жирный синий передний план на нормальном фоне».

Даниэль Н
источник
1
+1 для подробного объяснения и настройки параметров для варианта использования!
gertvdijk
Забавно, когда я пытаюсь это сделать с помощью: grep -R --color = always keyword1. | grep keyword2 // выделено только первое ключевое слово. Как я могу адаптировать ваш ответ для работы с рекурсивным поиском?
TenLeftFingers
1
Это странно, grep -R --color=always keyword1 . | grep keyword2должно работать. Вы перенаправив вывод снова (например, по конвейеру второй grepв less -R)? Если это так, вам нужно добавить и --color=alwaysко второму.
Даниэль Х
Отличный ответ! Чтобы выделить и то, и другое, --color=autoпонадобится второе grep, сразу после 'keyword2'.
Луис
@ Luis Да, вы правы, что Grep, по крайней мере, часто по умолчанию не использует цвета (хотя это может быть опцией настройки времени? Я не думаю, что это было переопределено в 2013 году, когда он работал на моей машине без этого…). Я добавил --color=alwaysк ответу, потому что вы можете захотеть передать это lessили что-то еще.
Даниэль Х
3

Попробуйте использовать действительные регулярные выражения, а не передавайте их другим экземплярам grep, например:

grep -E "\<foo\>.*\<bar\>" file

Это ограничивает соответствие строк, в которых эти ключевые слова совпадают только в этом порядке, к сожалению. В любом случае, использование grepв вашем вопросе довольно неэффективно, и вы должны избегать этого. Ответ @DanielH довольно намного проще для вашего случая, наверное.

Для соответствия ключевых слов 'или', я использую это регулярно:

grep -E "(foo|bar)" file
gertvdijk
источник
1
Я думаю, что OP хочет только строки, содержащие оба ключевых слова (команда, которую вы дали, дает все строки, которые содержат одно из них).
Даниэль Х
@DanielH Спасибо за указание на это. Я обновил свой ответ.
gertvdijk
Разве это не работает, только если foo появляется перед баром? Я не знаю, есть ли лучший способ, чем foo.*bar|bar.*foo, или если это даже необходимо для этого случая (который, как представляется, файл журнала, который, вероятно, будет иметь стандартный порядок для ключевых слов). Я добавил свой ответ до того, как вы обновили свой, но я буду держать его в курсе, если возникнет ситуация, когда цепочка greps действительно необходима (или в любое другое время, когда цветной вывод не следует отправлять на терминал, например grep | less -R).
Даниэль Х