Colorized grep - просмотр всего файла с выделенными совпадениями


509

Я считаю , grep«s --color=alwaysфлаг , чтобы быть чрезвычайно полезным. Однако grep печатает только строки с совпадениями (если только вы не запросите контекстные строки). Учитывая, что каждая печатаемая строка имеет соответствие, выделение не добавляет столько возможностей, сколько могло бы.

Мне бы очень хотелось, чтобы catфайл и увидеть весь файл с выделенными совпадениями шаблонов.

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


1
если вы хотите использовать более одного цвета для более чем одного шаблона (например, сообщения об ошибках, предупреждения, информация и т. д.), используйтеsed . sedрешение получает вас несколько цветов за счет дополнительной сложности (вместо примерно 30 символов , имеющих около 60 символов).
— Тревор Бойд Смит

С помощью sed вы можете даже выделить + код возврата возврата , см. Пример: askubuntu.com/a/1200851/670392
— Noam Manos

Ответы:


797

Вот несколько способов сделать это:

grep --color -E 'pattern|$' file
grep --color 'pattern\|$' file
egrep --color 'pattern|$' file

152
Это хитрый трюк! Хорошо, я должен помнить это. Для тех из вас, кто не разбирается в регулярных выражениях, «pattern | $» будет соответствовать строкам, которые имеют шаблон, который вы ищете, и строкам AND, имеющим конец, то есть всем им. Поскольку конец строки - это не символы, цветная часть вывода будет просто вашим шаблоном. Спасибо Райан!
— Зслайтон

55
Вы также можете опустить "$": egrep --color "pattern|" file(credit stackoverflow.com/a/7398092/50979 )
— 13рен

15
@ Zack, "|" оператор - оператор OR, а не оператор AND,
— JBoy

16
@JBoy, я использовал 'AND' обычным английским, а не логическим способом. Вы правы, это действительно оператор 'или' - он соответствует тому и другому. : P Хорошее уточнение.
— zslayton

12
Похоже, что "$" необходимо, если соответствует более одного шаблона. egrep --color "pattern1|pattern2|$", В противном случае цветовая подсветка не происходит.
— Застер

91

Вот что-то в том же духе. Скорее всего, вы будете использовать меньше, так что попробуйте это:

less -p pattern file

Он выделит шаблон и перейдет к его первому появлению в файле.


4
Также работает с трубопроводом (чтение из stding) с использованием -:… | less -p pattern -
— phk

3
@phk: Вы даже можете опустить тире.
— Приостановлено до дальнейшего уведомления.

Кроме того, добавление -iпараметра сделает регистр нечувствительным, как в less -ip pattern file.
— steveb

... и если конвейер в ANSI-цветной вводе, обеспечивает lessс -Rпереключателем:… | less -Rip introduction -
— Abdull

48

Я хотел бы порекомендовать ack - лучше, чем grep, мощный инструмент поиска для программистов .

Файлы шаблонов $ ack --color --passthru --pager = "$ {PAGER: -less -R}"
файлы шаблонов $ ack --color --passthru | меньше -R
$ export ACK_PAGER_COLOR = "$ {PAGER: -less -R}"
Файлы шаблонов $ ack --passthru

Мне это нравится, потому что он по умолчанию выполняет рекурсивный поиск по каталогам (и делает это намного умнее grep -r), поддерживает полные регулярные выражения Perl (а не POSIXish regex(3)) и имеет намного более приятное отображение контекста при поиске многих файлов.


2
Однако время от времени он не находит то, что я хочу, когда я уверен, что это должно быть там. ackумный, но иногда слишком умный, и он исключает тип файла, в котором было попадание.
— Майкл Пифель

4
@MPi ack -aбудет искать все типы файлов, в то же время исключая их .git/ .svn/и т. Д.
— ephemient

1
Тем не менее, это круто, что ackне просматривает мои изображения, поэтому -aделает слишком много. Я добавил --type-set=freemarker=.ftlк своему ~/.ackrc, чтобы привести один пример.
— Майкл Пифель

3
С помощью нескольких настроек конфигурации grep уже делает все, что делает ack, работает быстрее и никогда не пропускает результаты, как это иногда делают белые списки ack. Возможно сохраните ваши предпочтительные настройки grep в .bashrc. Мой читает: function grp () {GREP_OPTIONS = "- rI --color --exclude-dir = \. Git --exclude = tags" grep "$ @"
— Джонатан Хартли

22

Вы можете использовать мой highlightскрипт из https://github.com/kepkin/dev-shell-essentials

Это лучше, чем grepпотому, что вы можете выделить каждый матч своим цветом .

$ command_here | highlight green "input" | highlight red "output"

Снимок экрана из проекта Github


3
Вопрос прямо задан для использования решения grep, которое является стандартной утилитой на машинах с * nix.
— Зслайтон

1
Этот сценарий хорош, но не так хорош, как coloutупомянуто в другом ответе.
— Джонатан Хартли

@JonathanHartley И почему это так? Я не вижу причин для этого. Кроме того, этот скрипт использует гораздо более простую реализацию, чем colout, что хорошо, если вы хотите проверить, что он делает.
— Hellogoodbye

@ Привет, до свидания. Да, честно. Я должен держаться за суждение. colout более тщательный и мощный, но вы правы в том, что его соответственно сложнее использовать и перепроектировать.
— Джонатан Хартли

@JonathanHartley имеет смысл, что он более мощный!
— Hellogoodbye

19

Вы также можете создать псевдоним. Добавьте эту функцию в ваш .bashrc (или .bash_profile на osx)

function grepe {
    grep --color -E "$1|$" $2
}

Теперь вы можете использовать псевдоним как это: " ifconfig | grepe inet" или " grepe css index.html".

(PS: не забудьте source ~/.bashrcперезагрузить bashrc на текущей сессии)


Вы также можете использовать просто использовать egrep, если он доступен в вашей системе.
— Том

1
Конвейер результата этого меньше теряет информацию о цвете. Как вы могли бы предотвратить это?
— Коннор Кларк

5
@Hoten использовать --color=alwaysвместо--color
— limp_chimp

3
И, чтобы сделать lessинтерпретацию цветовых кодов, используйте less -R.
— Элия ​​Каган

Использование без кавычек $ 2 не является безопасным. В bash я бы лучше сделал функцию grepe () {local pattern = "$ 1" shift egrep --color "$ pattern | ^" "$ @"} Извините за беспорядок форматирования.
— Роберт Клемм

16

Используйте coloutпрограмму: http://nojhan.github.io/colout/

Он предназначен для добавления цветных бликов в текстовый поток. Имея регулярное выражение и цвет (например, «красный»), он воспроизводит текстовый поток с выделенными совпадениями. например:

# cat logfile but highlight instances of 'ERROR' in red
colout ERROR red <logfile

Вы можете связать несколько вызовов, чтобы добавить несколько разных цветов:

tail -f /var/log/nginx/access.log | \
    colout ' 5\d\d ' red | \
    colout ' 4\d\d ' yellow | \
    colout ' 3\d\d ' cyan | \
    colout ' 2\d\d ' green

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

vagrant status | \
    colout \
        '\''(^.+  running)|(^.+suspended)|(^.+not running)'\'' \
        green,yellow,red

1
Как отмечалось в другом месте, этот вопрос явно задавался для решения с использованием grep, который является стандартной утилитой на машинах, работающих под управлением * nix.
— Зслайтон

4
@ Зак, извини. На самом деле, если вы расширите проблему за пределы grep, и она уже раскрыта в ответах, coloutэто лучшее решение для вашей проблемы, лучшее, что я знаю. В соответствии с философией UNIX, программы должны быть написаны, чтобы делать одну вещь хорошо. Ибо grepэто фильтрация текстового потока. Ибо coloutэто раскраска или выделение текстового потока.
— user2683246

Это лучший ответ, потому что он может применять несколько разноцветных бликов и coloutявляется таким широко полезным инструментом. Изучите его один раз, используйте его во многих ситуациях, а не изучайте один инструмент для выделения лог-файлов, другой для выделения результатов теста и т. Д.
— Джонатан Хартли

9

Я использую rcg из "Linux Server Hacks", О'Рейли. Это идеально подходит для того, что вы хотите, и может выделить несколько выражений, каждое из которых имеет разные цвета.

#!/usr/bin/perl -w
#
#       regexp coloured glasses - from Linux Server Hacks from O'Reilly
#
#       eg .rcg "fatal" "BOLD . YELLOW . ON_WHITE"  /var/adm/messages
#
use strict;
use Term::ANSIColor qw(:constants);

my %target = ( );

while (my $arg = shift) {
        my $clr = shift;

        if (($arg =~ /^-/) | !$clr) {
                print "Usage: rcg [regex] [color] [regex] [color] ...\n";
                exit(2);
        }

        #
        # Ugly, lazy, pathetic hack here. [Unquote]
        #
        $target{$arg} = eval($clr);

}

my $rst = RESET;

while(<>) {
        foreach my $x (keys(%target)) {
                s/($x)/$target{$x}$1$rst/g;
        }
        print
}

7

-zВариант для Grep также довольно скользкий!

cat file1 | grep -z "pattern"

что это делает? -z говорит grep использовать ASCII NUL в качестве разделителя строк ...
— vy32

6

Я добавил это в мой .bash_aliases:

highlight() {
  grep --color -E "$1|\$"
}

3

Чтобы выделить шаблоны при просмотре всего файла, h может сделать это.

Плюс он использует разные цвета для разных узоров.

cat FILE | h 'PAT1' 'PAT2' ...

Вы можете также направить вывод hв less -Rдля лучшего чтения.

Чтобы использовать grep и использовать 1 цвет для каждого шаблона, cxpgrep может подойти.


1

Хорошо, это один из способов,

wc -l filename

даст вам количество строк - скажем, NN, то вы можете сделать

grep -C NN --color=always filename

3
«-C 2147483647», если вы не хотите сначала wc. Использование большого числа не замедляет процесс.
— Баррикартер

1

Вот скрипт оболочки, который использует функцию gwub от Awk, чтобы заменить искомый текст правильной escape-последовательностью, чтобы он отображался ярко-красным:

#! /bin/bash
awk -vstr=$1 'BEGIN{repltext=sprintf("%c[1;31;40m&%c[0m", 0x1B,0x1B);}{gsub(str,repltext); print}' $2

Используйте это так:

$ ./cgrep pattern [file]

К сожалению, он не обладает всеми функциями grep.

Для получения дополнительной информации вы можете обратиться к статье « Так вам нравится цвет » в Linux Journal


1

В другом ответе упоминается ключ -Cn от grep, который содержит n строк Context. Иногда я делаю это с n = 99 как быстрый и грязный способ получить [по крайней мере] скриншот из контекста, когда шаблон egrep кажется слишком неудобным, или когда я на машине, на которой я не установил rcg и / или ccze.

Я недавно обнаружил, cczeчто это более мощный колоризатор. Моя единственная жалоба заключается в том, что она ориентирована на экран (например less, которую я никогда не использую по этой причине), если вы не укажете ключ -A для вывода «raw ANSI».

+1 за rcgупоминание выше. Это все еще мой фаворит, так как его так легко настроить под псевдонимом. Примерно так обычно есть в моем ~ / .bashrc:

псевдоним tailc = 'tail -f / my / app / log / file | rcg отправить "BOLD GREEN" получить ошибку "CYAN" "RED" '


1

еще один грязный путь:

grep -A80 -B80 --color FIND_THIS IN_FILE

Я сделал

alias grepa='grep -A80 -B80 --color'

в башрч.


1
это проблематично, если вещей, которые вы ищете, там нет. Скажите из-за ошибки, в этом случае вы ничего не получите.
— Пол Рубел


0

Если вы хотите выделить несколько рисунков разными цветами, посмотрите этот скрипт bash.

Основное использование:

echo warn error debug info 10 nil | colog

Вы можете изменить шаблоны и цвета во время работы, нажав одну клавишу, а затем введите клавишу.


0

Я использую следующую команду для аналогичной цели:

grep -C 100 searchtext file

Это скажет grep, чтобы напечатать 100 * 2 строки контекста, до и после выделенного поискового текста.


0

Вот мой подход , вдохновленный решением @ kepkin:

# Adds ANSI colors to matched terms, similar to grep --color but without
# filtering unmatched lines. Example:
#   noisy_command | highlight ERROR INFO
#
# Each argument is passed into sed as a matching pattern and matches are
# colored. Multiple arguments will use separate colors.
#
# Inspired by https://stackoverflow.com/a/25357856
highlight() {
  # color cycles from 0-5, (shifted 31-36), i.e. r,g,y,b,m,c
  local color=0 patterns=()
  for term in "$@"; do
    patterns+=("$(printf 's|%s|\e[%sm\\0\e[0m|g' "${term//|/\\|}" "$(( color+31 ))")")
    color=$(( (color+1) % 6 ))
  done
  sed -f <(printf '%s\n' "${patterns[@]}")
}

Это принимает несколько аргументов (но не позволяет настраивать цвета). Пример:

$ noisy_command | highlight ERROR WARN

-1

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

Option -C999сделает свое дело при отсутствии опции для отображения всех контекстных строк. Большинство других вариантов grep также поддерживают это. Однако: 1) вывод не производится, если совпадения не найдено, и 2) эта опция отрицательно влияет на эффективность grep: когда-C значение велико, многие строки могут быть временно сохранены в памяти, чтобы grep определил, какие строки контекста отображать, когда происходит совпадение. Обратите внимание, что реализации grep не загружают входные файлы, а читают несколько строк или используют скользящее окно поверх ввода. Часть «before» контекста должна храниться в окне (памяти), чтобы вывести строки контекста «before» позже, когда найдено совпадение.

Шаблон, такой как ^|PATTERN или PATTERN|$любой другой под-шаблон, соответствующий пустому совпадению, такой как [^ -~]?|PATTERNхороший трюк. Тем не менее, 1) эти шаблоны не показывают несоответствующие строки, выделенные как контекст, и 2) это не может быть использовано в сочетании с некоторыми другими опциями grep, такими как -Fи-w , например.

Так что ни один из этих подходов не устраивает меня. Я использую ugrep и расширенный grep с возможностью -yэффективно отображать все несоответствующие выходные данные в виде выделенных цветом строк контекста. Другие инструменты, подобные grep, такие как ag и ripgrep, также предлагают возможность сквозного доступа. Но ugrep совместим с GNU / BSD grep и предлагает расширенный набор опций grep, таких как -yи -Q. Например, вот что -yотображается в сочетании с -Q(интерактивный интерфейс запросов для ввода шаблонов):

ugrep -Q -y FILE ...

Зачем голосовать, не оставляя комментарий? Более чем справедливо упомянуть альтернативные инструменты grep, как и некоторые другие ответы.
— Доктор Алекс RE
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.