Подтвердить что ты не робот

Выход Grep с несколькими цветами?

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

Таким образом, строка, соответствующая значениям MALE и AUGUST выдаст MALE синим цветом, а AUGUST оранжевым? Я открыт для использования sed, awk, grep и crayons или других.

4b9b3361

Ответ 1

Вы можете каскад greps с разными цветами, указав --color = always и используя регулярное выражение 'foo | $' для передачи всех строк.

Например:

tail -f myfwlog | GREP_COLOR='01;36' egrep --color=always 'ssh|$' | GREP_COLOR='01;31' egrep -i --color=always 'drop|deny|$'

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

.... GREP_COLOR='01;31' egrep -i --color=always '^.*drop.*$|^.*deny.*$|$'

Ответ 2

grep является регулярным выражением, а не синтаксическим ярлыком:). Вам нужно будет использовать несколько вызовов grep, используя для каждого значения GREP_COLOR другое значение.

GREP_COLOR="1;32" grep foo file.txt | GREP_COLOR="1;36" grep bar

Это означало бы "foo" и "bar" в разных цветах в строках, которые соответствуют обоим. Я не думаю, что есть (простой) способ обрабатывать все вхождения любого шаблона, нежели слияние выходного потока двух независимых вызовов:

{ GREP_COLOR="1;32" grep foo file.txt
  GREP_COLOR="1;36" grep bar file.txt
} | ...

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


Вы можете использовать awk для замены каждого совпадения самим собой, заключенным в правильный код управления.

 echo "foo bar" | awk '{ gsub("bar", "\033[1;33m&\033[0m");
                         gsub("foo", "\033[1;36m&\033[0m"); print }'

В каждой строке вы глобально замените все, что соответствует данному регулярному выражению, с самим собой (&), завернутым в escape-последовательности ANSI для желаемого цвета (что grep --color для вас). После обработки всех возможных совпадений вам нужно явно напечатать строку.

Ответ 3

Если вы хотите что-то из коробки, вы, вероятно, ищете hhighlighter.

Вот пример: JBoss output

Посмотрите. Это невероятно полезно для раскраски слов разных цветов автоматически. Это впечатляющий проект, построенный поверх ack.

Ответ 4

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

Вы можете загрузить исходный код из GitHub:

git clone http://github.com/mbornet-hl/hl

тогда:

cd hl/cr; make

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

hl: version 1.21
Usage: hl [-h|-eidD][-E][-rgybmcwRGYBMCW] regexp ...
  -h : help
  -v : version
  -u : do not bufferize output on stdout
  -e : extended regular expressions
  -i : ignore case
  -E : print on stderr
  -r : red
  -g : green
  -y : yellow
  -b : blue
  -m : magenta
  -c : cyan
  -w : white
  -R : red     (reverse video)
  -G : green   (reverse video)
  -Y : yellow  (reverse video)
  -B : blue    (reverse video)
  -M : magenta (reverse video)
  -C : cyan    (reverse video)
  -W : white   (reverse video)
  -d : debug
  -D : display regular expressions

Чтобы раскрасить слово "красный" красным цветом, а слово "синий" синим цветом, вам просто нужно ввести следующую команду:

echo "red blue red blue" | hl -r red -b blue

и вот пример, чтобы выделить вывод команды ifconfig:

hl -ei -m '^(eth|(vir)?br|vnet)[0-9.]*:[0-9]+\>'             \
       -b '^(eth|(vir)?br|vnet)[0-9.]*\.[0-9]+\>'            \
       -c '([0-9a-f]{2}:){5}[0-9a-f]{2}'                     \
       -g '\<UP\>|\<RUNNING\>|([0-9]{1,3}\.){3}[0-9]{1,3}\>' \
       -y '^(eth|(vir)?br|vnet)[0-9.:]*\>'                   \
       -W '[0-9a-f]{4}::[0-9a-f]{4}\:[0-9a-f]{4}:[0-9a-f]{4}:[0-9a-f]{4}' \
       -r ' (errors|dropped|overruns):[^0][0-9]*'

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

Надеюсь, что это поможет.

Ответ 5

Попробуйте замечательный rpen http://github.com/rtulke/rpen

требуется egrep или grep

cp rpen.py/usr/local/bin/rpen chmod 777/usr/local/bin/rpen

затем попробуйте

ps xau | rpen Ss "S +" "\? \?"

Ответ 6

Так что здесь версия с использованием sed. Допустим, вы хотите, чтобы слово "FAILED" было окрашено в красный цвет:

sed 's/\(ERROR\)/\o033[31m\1\o033[39m/'

Чтобы вся строка, содержащая слово "FAILED", была отмечена красным:

sed 's/\(.*ERROR.*\)/\o033[31m\1\o033[39m/'

Чтобы несколько слов были помечены красным:

sed 's/\(ERROR\|FAILED\)/\o033[31m\1\o033[39m/'

Чтобы несколько слов и их линии были отмечены красным:

sed 's/\(.*FAILED.*\|.*ERROR.*\)/\o033[31m\1\o033[39m/'

Чтобы иметь несколько цветов (ERROR = красный /FAILED = синий)

sed -e 's/\(ERROR\)/\o033[31m\1\o033[39m/' -e 's/\(FAILED\)/\o033[34m\1\o033[39m/'

Чтобы использовать все это через ssh:

ssh [email protected] -t "tail -n 1024 -f /some/log/file | sed --unbuffered -e 's/\(.*ERROR.*\|.*FAILED.*\)/\o033[31m\1\o033[39m/' -e 's/\(.*postfix.*\|.*dhcpd.*\)/\o033[32m\1\o033[39m/'"

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

Для других цветов ищите коды ANSI.

Ответ 7

Как насчет этого? Вы можете сделать это с помощью grep ТОЛЬКО! Трюки здесь: (1) вы берете/ИЛИ/слова, которые вы ищете; (2) вы используете опции -A и -B с достаточно большими номерами (больше, чем количество строк вашего файла).

echo "you make it" > tmp
echo "you take it" >> tmp
echo "you cake it" >> tmp
echo "you bake it" >> tmp
echo "you wake it" >> tmp

GREP_COLOR='1;32' grep -P "(take|cake|bake)" --color=always tmp | GREP_COLOR='1;33' grep -P "(cake|bake)" --color=always -A10000 -B10000 | GREP_COLOR='1;34' grep -P "(bake)" --color=always -A10000 -B10000 

Ответ 8

cxpgrep подходит именно для этой цели - выделяет шаблоны разных цветов.

cxpgrep 'PAT1|PAT2|...' FILE_OR_DIRECTORY

Ответ 9

Мой ответ ниже:

tailf logfile awk '/MALE/' {print "\033[34m" $0 "\033[39m"}  '/MALE/' {print "\033[33m" $0 "\033[39m"}