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

Регулярное совпадение цвета - без опускающихся промахов

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

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

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

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

INPUT:

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

Regex:

  • "* красный"

ВЫВОД:

  • fred (красным)
  • Ted
  • красный (красный)
  • свинец

Чтобы я мог:

list_stuff | color_grep "make_this_stand_out_but_dont_hide_the_rest"

EDIT:

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

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

В частности, script (который я модифицировал/упростил): 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"
}

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

4b9b3361

Ответ 1

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

Ответ 2

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

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

#!/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

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

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

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

autoload colors zsh/terminfo

)

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

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

Ответ 4

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

Ответ 5

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

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

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

Ответ 6

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

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

Заголовки выглядят следующим образом:

== > access.log < ==

Меня смутили быстрые изменения между различными лог файлами, поэтому этот файл 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

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