«Grep», который выделяет вместо фильтрации

Вопрос или проблема

Мне интересно, есть ли в стандартном наборе инструментов Unix программа, такая как grep, которая вместо того, чтобы фильтровать строки, содержащие строку, просто выводит тот же ввод, но выделяя или окрашивая выбранную строку.

Я думал сделать это сам (должно быть достаточно просто), но, возможно, это уже существует как команда Unix.

Я планирую использовать это для мониторинга логов, поэтому я бы сделал что-то вроде этого:

tail -f logfile.log | highlight "error"

Обычно, когда я отслеживаю логи, мне нужно найти конкретную строку, но я также хочу знать, что написано до и после этой строки, поэтому фильтрация иногда недостаточна.

Существует ли что-то подобное?

Это забавный трюк с базовой командой grep. Он состоит из использования двух фильтров: того, который вы хотите применить, и фиктивного, который соответствует всем строкам, но не создает выделение. Этот фиктивный фильтр может быть как ^ (начало строки), так и $ (конец строки).

grep "^\|text" --color="always" file

или

grep -E "^|text" --color="always" file

Посмотрите пример:

$ cat a
hello this is 
some text i wanted
to share with you
$ grep "^\|text" --color="always" a
hello this is 
some text i wanted     # "text" выделен
to share with you

Существует инструмент под названием ack. Вы можете найти его на http://beyondgrep.com, и это действительно инструмент, превосходящий grep. Его самое распространенное использование заключается в выполнении такой задачи, как find . -name "*.java" --print | xargs grep clazz или подобной. Потому что мы делаем это все время.

Просто ack clazz, и вы получите вывод. Он выполняет поиск по соответствующим файлам (не пытается выполнять grep по двоичным файлам) и также позволяет получать вывод в цвете.

Если вы используете его с опцией --passthru, он будет выводить весь входной поток, выделяя подходящие области цветом.

--passthru Выводить все строки, независимо от того, соответствуют они или нет

Как говорится в документации, если для файла указать -, он будет принимать STDIN:

Если указаны какие-либо файлы или каталоги, проверяются только эти файлы и каталоги. Кроме того, ack может выполнять поиск по STDIN, но только если не указаны файлы или каталоги или если один из них – “-“.

Таким образом, извините за злоупотребление cat (и каламбур – см. ниже), вы можете это использовать:

$ cat file | ack --passthru pattern
$ cat file | ack --passthru pattern -

Это будет принимать вывод от пайпа и отправлять его через ack, который будет выводить все строки (с --passthru) с выделенным шаблоном.

Это именно тот инструмент, который вам нужен (и немного больше). Это стандартный пакет для многих менеджеров пакетов. См. http://beyondgrep.com/install/ для вашего любимого.

_   /|
\'o.O'
=(___)=
   U    ack --thpppt!

(Если вы не узнали, это Билл Кот, хотя поиск изображений может также помочь – не кликайте на наборы Майли Сайрус)

Вы могли бы использовать флаг grep -C, который дает n строк контекста, например, grep -C 3 будет выводить 3 строки до и после совпадения. Существуют также -B и -A для до и после.

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

Я поклонник hhighlighter от Паоло Антинори. https://github.com/paoloantinori/hhighlighter

Плюс этой команды в том, что она может выделять до 10 слов уникальными цветами. Просто направьте вывод команды в h с словами для выделения.

Например, tail -f /var/log/somelog.log | h "ERROR"
выдаст:

demo-1


Некоторые примеры с его сайта:

demo-2
demo-3

Я написал небольшой скрипт, который будет окрашивать любую строку, которую вы ему передадите:

#!/usr/bin/env perl
use Getopt::Std;
use strict;
use Term::ANSIColor; 

my %opts;
getopts('hic:l:',\%opts);
    if ($opts{h}){
      print<<EoF; 
Use -l to specify the pattern(s) to highlight. To specify more than one 
pattern use commas. 

-l : A Perl regular expression to be colored. Multiple expressions can be
     passed as comma separated values: -l foo,bar,baz
-i : делает поиск чувствительным к регистру
-c : список цветов, разделенный запятыми;

EoF
      exit(0);
    }

my $case_sensitive=$opts{i}||undef;
my @color=('bold red','bold blue', 'bold yellow', 'bold green', 
           'bold magenta', 'bold cyan', 'yellow on_magenta', 
           'bright_white on_red', 'bright_yellow on_red', 'white on_black');
if ($opts{c}) {
   @color=split(/,/,$opts{c});
}
my @patterns;
if($opts{l}){
     @patterns=split(/,/,$opts{l});
}
else{
    $patterns[0]='\*';
}

# Установка $| в ненулевое значение обеспечивает немедленную очистку и после каждой записи или печати на текущий выбранный канал вывода. 
$|=1;

while (my $line=<>) 
{ 
    for (my $c=0; $c<=$#patterns; $c++){
    if($case_sensitive){
        if($line=~/$patterns[$c]/){
           $line=~s/($patterns[$c])/color("$color[$c]").$1.color("reset")/ge;
        }
    }
    else{
        if($line=~/$patterns[$c]/i){
          $line=~s/($patterns[$c])/color("$color[$c]").$1.color("reset")/ige;
        }
      }
    }
    print STDOUT $line;
}

Если вы сохраните его как color в каталоге, который находится в вашем $PATH и сделаете исполняемым (chmod +x /usr/bin/color), вы можете выделять соответствующий шаблон так:

echo -e "foo\nbar\nbaz\nbib" | color -l foo,bib 

Это даст:

  enter image description here

Как написано, скрипт имеет предопределенные цвета для 10 различных шаблонов, поэтому, предоставляя ему список, разделенный запятыми, как в примере выше, он будет окрашивать каждый из совпадающих шаблонов в разные цвета.

Я написал программу для этого некоторого времени назад. Я называю ее cgrep (цветной grep).

Вы можете скачать ее, скопировав секцию кода отсюда в пустой файл: http://wiki.tcl.tk/38096

Затем сделайте файл исполняемым и скопируйте его в один из ваших регулярных каталогов bin.

Она написана на tcl, поэтому вам нужно установить tcl (версии 8.5 и выше). Но большинство дистрибутивов Linux уже включают tcl, так как много программного обеспечения его использует (gitk, настройка ядра, expect и т.д.).

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

tail -f logfile | cgrep '^.*WARNING.*$' -fg yellow '^.*ERROR.*$' -fg red -bg yellow

Вы можете использовать эту команду

grep --color --context=1000

Или короче

grep --col -1000

explainshell.com – grep –color –context

Самый простой способ выглядит следующим образом, как мне кажется:

tail -f logfile.log | grep -e 'error' -e '**'

enter image description here

Нет необходимости ничего устанавливать.

Ну, я использую Fedora 21, и если я наберу

grep -E \|kk rs.c

он выведет все содержимое файла “rs.c”, выделяя любые вхождения “kk”.

Простой трюк — также сопоставить пустую строку или начало строки; любое из них даст нулевое совпадение для всех строк:

grep --color -e 'REGEXP' -e ''
grep --color -e 'REGEXP' -e ^

Или (с использованием расширенного синтаксиса регулярных выражений):

grep --color -E 'REGEXP|'
egrep --color 'REGEXP|'

Используйте less. Строка поиска, найденная с помощью /, является регулярным выражением, и вхождения будут выделены.

В моем .bashrc у меня есть эта функция. Я называю ее cgrep, но здесь я даю ей немного более подходящее имя.

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

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

tail -f /var/log/SOMELOG | highlight KEYWORD

Вы можете просто направить ваш вывод на:

sed "s/\([Ee][Rr][Rr][Oo][Rr]\)/`tput rev`\1`tput rmso`/"

Здесь я использую регулярное выражение, которое будет совпадать с “error”, “ERROR”, “ErRoR” и т. д. во всех 32 возможных вариациях.

У меня в ~/.zshrc определена следующая функция:

hl () {
    sed s/$1/$'\e[1;31m'\&$'\e[0;m'/
}

Используйте ее с tail -f logfile.log | hl "error". Она добавляет escape-последовательность для Light Red перед выделенным словом и сброс на отсутствие цвета после слова. Вы можете найти другие цветовые коды здесь: http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html

.

Ответ или решение

Конечно, поиск и выделение ключевых слов в потоке данных — актуальная задача для многих ИТ-специалистов, особенно когда речь идет о мониторинге журналов (логов). Универсальный инструмент Unix "grep" позволяет выполнять поиск и фильтрацию строк, содержащих заданное регулярное выражение. Однако бывают случаи, когда необходимо не фильтровать, а лишь выделять требуемые строки в общем контексте данных.

Решение:

Чтобы выделять слова или фразы в потоке данных, вы можете воспользоваться рядом существующих решений, не создавая собственный инструмент с нуля. Вот несколько предложений:

  1. Использование grep для выделения:
    Команда grep может быть настроена на выделение найденных строк без их фильтрации. Использование флага --color позволяет подсветить совпавшую область текста:

    grep --color=always -E '^|Ваш_текст'

    Пример выше показывает весь текст с выделением искомого фрагмента без удаления остальных строк.

  2. Утилита ack:
    ack — более функциональный инструмент, который также может использоваться для выделения текста. Команда выглядит следующим образом:

    tail -f logfile.log | ack --passthru "error"

    Здесь --passthru обеспечивает отображение всех строк с выделением только совпадений, что идеально подходит для мониторинга в реальном времени.

  3. hhighlighter от Паоло Антинори:
    Еще один инструмент, hhighlighter, позволяет выделять сразу несколько ключевых слов разными цветами, что удобно для комплексного анализа журналов:

    tail -f logfile.log | h "ERROR" "WARNING"

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

  4. Использование sed для подсветки:
    Встроенный инструмент sed может использоваться для выделения текста с помощью управляющих последовательностей терминала:

    sed "s/Ваш_текст/`tput rev`&`tput sgr0`/g"

    Такой подход позволяет выделить любое слово или фразу, используя обратную и обычную видеоинверсию.

  5. Создание функции highlight в оболочке:
    В файле конфигурации вашей оболочки можно создать пользовательскую функцию:

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

    Это позволяет удобно интегрировать выделение текста в ваши стандартные рабочие процессы.

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

Оцените материал
Добавить комментарий

Капча загружается...