Мне было интересно, есть ли в общем наборе инструментов 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" is highlighted
to share with you
^
или $
и просто "|text"
работает.Есть инструмент под названием ack
. Вы можете найти его на http://beyondgrep.com , и это действительно инструмент, выходящий за рамки grep. Его наиболее распространенное использование - это заполнение этой роли find . -name "*.java" --print | xargs grep clazz
или тому подобное. Потому что мы делаем это все время.
Просто ack clazz
и вы получите результат. Ищет нужные файлы (не пытается выполнить поиск двоичных файлов) и также дает хороший цветной вывод.
Если вы используете его с --passthru
опцией, он будет печатать весь входной поток, выделяя совпадающие области цветом.
--passthru
Распечатайте все строки, независимо от того, совпадают они или нет
Как указано в документации, если -
используется для файла, он будет принимать STDIN:
Если указаны какие-либо файлы или каталоги, то проверяются только эти файлы и каталоги. ack также может выполнять поиск в STDIN, но только если не указаны аргументы файла или каталога или если один из них равен "-".
Таким образом, простите за cat
ругань ( и за каламбур - см. ниже ) у вас может получиться:
$ cat file | ack --passthru pattern
$ cat file | ack --passthru pattern -
Это возьмет вывод канала и отправит его, через ack
который будут напечатаны все строки (с --passthru
) с выделенным шаблоном.
Это именно тот инструмент, который вам нужен (и даже немного больше). Это стандартный пакет для многих менеджеров пакетов. См. http://beyondgrep.com/install/ для вашего фаворита.
_ /| \'оО' =(___)= Подтвердить --thpppt!
(Если вы не узнаете его, это кот Билл, хотя поиск изображений также может помочь — не нажимайте на набор Майли Сайрус)
grep -R
, я не понимаю, как это может помочь ОП.--passthru
опция напечатает все строки и выделит интересующие образцы. Точно так же для работы со STDIN можно использовать дефис в качестве «имени» файла или вообще не использовать аргументы файла.Вы можете использовать grep -C
флаг, который дает n строк контекста, например, grep -C 3
будет печатать 3 строки до и после совпадения. Так же есть -B
и -A
до и после.
Если вы хотите регулярно выделять заданные строки, например, определенные форматы журналов, возможно, стоит использовать python pygmentize с пользовательским лексером , поскольку он основан на регулярных выражениях, и вы будете удивлены, насколько это просто . Этот последний также имеет то преимущество, что является кросс-платформенным, хотя некоторые терминалы не очень хорошо отображают цвета.
Я поклонница хайлайтера Паоло Антинори. https://github.com/paoloantinori/hhighlighter
Плюсом этой команды является то, что она может выделять до 10 слов уникальными цветами. Просто передайте вывод команды h
со словами, которые нужно выделить.
Например tail -f /var/log/somelog.log | h "ERROR"
, будет производиться:
Я написал небольшой скрипт, который будет окрашивать любую строку, которую вы ему дадите:
#!/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 : makes the search case sensitive
-c : comma separated list of colors;
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]='\*';
}
# Setting $| to non-zero forces a flush right away and after
# every write or print on the currently selected output channel.
$|=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
Это произведет:
Как написано, сценарий имеет предопределенные цвета для 10 различных шаблонов, поэтому если указать список, разделенный запятыми, как в приведенном выше примере, каждый из шаблонов, совпавших с ним, будет окрашен в другой цвет.
Я написал программу, чтобы сделать это некоторое время назад. Я называю это cgrep (для цвета grep).
Вы можете скачать его, скопировав раздел кода отсюда в пустой файл: http://wiki.tcl.tk/38096
Затем сделайте файл исполняемым и скопируйте его в один из ваших обычных каталогов bin.
Он написан на tcl, поэтому вам необходимо установить tcl (8.5 и выше). Но большинство дистрибутивов Linux в любом случае установили бы tcl, так как многие программы используют его (gitk, конфигурация ядра, ожидания и т. д.).
Синтаксис раскраски прост: regex option option ..
. Вы можете иметь столько регулярных выражений, сколько хотите. Вот пример, в котором ошибки окрашиваются в красный цвет, а предупреждения — в желтый:
tail -f logfile | cgrep '^.*WARNING.*$' -fg yellow '^.*ERROR.*$' -fg red -bg yellow
Ну, у меня Fedora 21, и если я наберу
grep -E \|kk rs.c
он выведет все содержимое файла «rs.c», выделяя любые вхождения «kk».
Вы можете использовать эту команду
grep --color --context=1000
Или короче
grep --col -1000
Простой трюк состоит в том, чтобы также сопоставить пустую строку или начало строки; либо приводит к совпадению нулевой длины для всех строк:
grep --color -e 'REGEXP' -e ''
grep --color -e 'REGEXP' -e ^
Или (расширенный синтаксис регулярного выражения):
grep --color -E 'REGEXP|'
egrep --color 'REGEXP|'
REGEX
? Я только что попробовал, и это так. Так что это не соответствует требованиям (только выделение, а не фильтр). Но второй вариант действительно делает то, что запросил ОП (проверено;).REGEX
(выделяет этот термин) и по «ничего» (то есть «везде»). Могу ли я предложить вам включить это небольшое объяснение (слишком ясно, что оно делает), а затем мы удалим наши комментарии (для очистки)? Спасибо! А пока +1 от меня :)Используйте 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» и т. д. во всех 32 возможных вариантах.
У меня есть следующая функция, определенная в моем ~/.zshrc
:
hl () {
sed s/$1/$'\e[1;31m'\&$'\e[0;m'/
}
Используйте его с tail -f logfile.log | hl "error"
. Он добавляет escape-последовательность для светло-красного перед выделенным словом и сбрасывает цвет после слова. Вы можете найти другие цветовые коды здесь: http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html
Мартино Дино
Мог говорит восстановить Монику