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.