Цветовые регулярные выражения - без промахов - PullRequest
19 голосов
/ 27 октября 2008

При использовании grep --color=always я могу получить красивую цветную подсветку для совпадений регулярных выражений.

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

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

Если мое описание не очевидно, я хочу:

INPUT:

  • Фреда
  • 1018 * Ted *
  • красный
  • свинец

Regex:

  • "* красный"

ВЫВОД:

  • Фред (в красном)
  • 1036 * Ted *
  • красный (красный)
  • свинец

Чтобы я мог сделать:

list_stuff | color_grep "make_this_stand_out_but_dont_hide_the_rest"

EDIT:

Я нашел решение, которое не очень красиво, но работает:

Благодаря: http://www.pixelbeat.org/docs/terminal_colours/

В частности, скрипт (который я модифицировал / упростил): http://www.pixelbeat.org/talks/iitui/sedgrep

function sedgrep ()
{
    C_PATT=`echo -e '\033[33;01m'`
    C_NORM=`echo -e '\033[m'`

    sed -s "s/$1/${C_PATT}&${C_NORM}/gi"
}

Все еще ищем более простой способ сделать это!

Ответы [ 7 ]

20 голосов
/ 04 января 2012

Самое простое решение было бы использовать egrep --color=always 'text|^', который бы соответствовал всем началам строки, но только окрашивал нужный текст.

7 голосов
/ 28 ноября 2012

Вот скрипт, который я использую для раскрашивания вывода.

Я думаю, что нашел идею / фрагмент в каком-то блоге или учебнике по bash / sed - больше не могу найти, это было очень давно.

#!/bin/bash

red=$(tput bold;tput setaf 1)            
green=$(tput setaf 2)                    
yellow=$(tput bold;tput setaf 3)         
fawn=$(tput setaf 3)
blue=$(tput bold;tput setaf 4)           
purple=$(tput setaf 5)
pink=$(tput bold;tput setaf 5)           
cyan=$(tput bold;tput setaf 6)           
gray=$(tput setaf 7)                     
white=$(tput bold;tput setaf 7)          
normal=$(tput sgr0)                      

sep=`echo -e '\001'` # use \001 as a separator instead of '/'

while [ -n "$1" ] ; do
  color=${!1}
  pattern="$2"
  shift 2

  rules="$rules;s$sep\($pattern\)$sep$color\1$normal${sep}g"
done

#stdbuf -o0 -i0 sed -u -e "$rules"
sed -u -e "$rules"

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

./colorize.sh color1 pattern1 color2 pattern2 ...

, например

dmesg | colorize.sh red '.*Hardware Error.*' red 'CPU[0-9]*: Core temperature above threshold' \
green 'wlan.: authenticated.*' yellow 'wlan.: deauthenticated.*'

Не очень хорошо работает с перекрывающимися шаблонами, но я все равно нашел это очень полезным.

НТН

3 голосов
/ 28 октября 2008

Эта маленькая функция хорошо работает в моей ZShell:

function color_grep {
    sed s/$1/$fg[yellow]$1$terminfo[sgr0]/g
}

(* Потребности 1004 *

autoload colors zsh/terminfo

)

Может быть, вы можете сделать что-то подобное?

Редактировать: Извините, это не будет работать с регулярными выражениями. Вам придется немного подправить ...

1 голос
/ 28 октября 2008

Вы можете использовать опцию -C<num>, чтобы отобразить <num> строки контекста вокруг вашего матча. Просто убедитесь, что <num> не меньше, чем количество строк в вашем файле.

1 голос
/ 28 октября 2008

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

function colormatch ()
{
    tee - | grep --color=always $1 | sort | uniq
}

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

0 голосов
/ 12 февраля 2010

Я копаю эту маленькую утилиту python. Если не в Debian, используйте alien для конвертации в rpm.

http://korpus.juls.savba.sk/~garabik/software/grc.html

regexp=.*red
colours="\033[38;5;160m"
count=once

Это хорошая страница о цветах терминала.

http://www.pixelbeat.org/docs/terminal_colours/

(Английский у королевы такой яркий.)

0 голосов
/ 09 января 2009

Я недавно сделал нечто похожее на фильтр. Я использую его для раскрашивания «заголовков» в хвосте несколькими файлами, например:

tail -f access.log error.log foo.log | logcol.sh

Заголовки выглядят так:

==> access.log <== </p>

Меня смутили быстрые изменения между различными лог-файлами, поэтому этот logcol.sh помогает. ==> жестко задан для конкретного использования, но также может быть параметром.

#!/bin/sh
while read line
do
  if test `expr "$line" : "==>.*"`  -eq 0 ;
  then
    printf '\033[0m%s\n' "$line"
  else
    printf '\033[0;31m%s\n' "$line"
  fi
done

Возможно, не самый элегантный, но я думаю, что он вполне читабелен. Я надеюсь, что у меня нет опечаток ;-) НТН, грабят

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...