Como você colorir apenas algumas palavras-chave para um script bash?

10

Estou executando algum código de teste de unidade. O código de teste da unidade gera um texto regular. Há muito do texto, por isso quero destacar para o usuário palavras-chave importantes.

Neste caso, as palavras-chave são "PASS" e "FAIL".

Como você colorir "PASS" para ser verde e "FAIL" para ser vermelho?

    
por Trevor Boyd Smith 28.08.2012 / 23:43

5 respostas

5

Aqui está um script de propósito geral para colorir padrões de regex (provavelmente precisa de alguns retoques):

#! /bin/bash

color_to_num () {
  case $1 in
    black)  echo 0;;
    red)    echo 1;;
    green)  echo 2;;
    yellow) echo 3;;
    blue)   echo 4;;
    purple) echo 5;;
    cyan)   echo 6;;
    white)  echo 7;;
    *)      echo 0;;
  esac
}

# default values for foreground and background colors
bg=
fg=
bold="$(tput bold)"
italics=""
boundary=""

while getopts f:b:sli option; do
  case "$option" in
    f) fg="$OPTARG";;
    b) bg="$OPTARG";;
    s) bold="";;
    l) boundary=".*";;
    i) italics="$(tput sitm)";;
  esac
done

shift $(($OPTIND - 1))

pattern="$*"

if [ -n "$fg" ]; then
  fg=$(tput setaf $(color_to_num $fg))
fi
if [ -n "$bg" ]; then
  bg=$(tput setab $(color_to_num $bg))
fi

if [ -z "$fg$bg" ]; then
  fg=$(tput smso)
fi

sed "s/${boundary}${pattern}${boundary}/${bold}${italics}${fg}${bg}&$(tput sgr0)/g"

Nomeie-o com hilite.sh e use-o desta forma:

$ ./BIN_PROGRAM | hilite.sh -f green PASS | hilite.sh -f red FAIL

$ # Here is an example one liner
$ echo -e "line 1: PASS\nline 2: FAIL" | hilite.sh -f green PASS | hilite.sh -f red FAIL
    
por 04.07.2018 / 04:15
7

supercat parece fazer o que você está procurando.

Package: supercat
Description-en: program that colorizes text for terminals and HTML
 Supercat is a program that colorizes text based on matching regular
 expressions/strings/characters. Supercat supports html output as well
 as standard ASCII text. Unlike some text-colorizing programs that
 exist, Supercat does not require you to have to be a programmer to
 make colorization rules.
Homepage: http://supercat.nosredna.net/

Não parece haver nenhuma maneira de dizer o que colorir na linha de comando, você tem que especificar um arquivo de configuração.

Parece que lembro que costumava haver um programa chamado 'hilite' ou 'hl' que destacava o texto que correspondia a um padrão (como grep --colour , mas exibindo linhas não correspondentes também), mas não consegui encontrá-lo quando eu procurei por ele.

Finalmente, GNU grep pode ser usado para destacar padrões - mas somente uma cor pode ser usada (ou seja, você não pode ter PASS em verde e FAIL em vermelho, ambos seriam destacados com a mesma cor).

Canalize seus dados por meio de algo assim:

egrep --color "\b(PASS|FAIL)\b|$"

Este exemplo usa egrep (também conhecido como grep -E ), mas -G basic regexp, -F fixed-string e -P PCRE também funcionam.

Todos os jogos serão destacados. O padrão é vermelho ou defina o GREP_COLOR env var.

A chave para esse trabalho é que o% final% co_de no padrão corresponde ao fim de linha (ou seja, todas as linhas correspondem), portanto todas as linhas serão exibidas (mas não coloridas).

Os |$ são marcadores de limite de palavras para corresponder a, por exemplo. FALHA, mas não FALHA. eles não são necessários, então remova-os se quiser combinar palavras parciais.

Aqui está o script wrapper de exemplo para o supercat que eu escrevi ontem. Ele funciona, mas, ao escrevê-lo, descobri que o supercat não tem nenhuma opção para pesquisas que não diferenciam maiúsculas de minúsculas. IMO, que torna o programa significativamente menos útil. No entanto, simplificou bastante o script porque não precisei escrever uma opção '-i':)

#! /bin/bash 

# Requires: tempfile from debian-utils, getopt from util-linux, and supercat

SCRIPTNAME=$(basename $0)
CFGFILE=$(tempfile -p spc)

usage() {
  cat <<__EOF__
Highlight regexp patterns found on stdin or files specified on command
line with specified colours.

Usage: $SCRIPTNAME [ --colour "pattern" ...] [FILE]

Options:

        -k,--black   regexp
        -r,--red     regexp
        -g,--green   regexp
        -y,--yellow  regexp
        -b,--blue    regexp
        -m,--magenta regexp
        -c,--cyan    regexp
        -w,--white   regexp

Example:

    run-script.sh | $SCRIPTNAME --green PASS --red FAIL

__EOF__
  exit 0
}


# Format definition from the spc man page:
#1234567890123456789012345678901234567890123456789012345
#HTML Color Name      Col A N T RE / String / Characters
FMT="%-20s %3s %1s %1s %1s (%s)\n"

add_color_to_config() {
  COLOR="$1"
  PATTERN="$2"

  printf "$FMT" "$COLOR" "$COLOR" - 0 r "$PATTERN" >> "$CFGFILE"
}


# uses the "getopt" program from util-linux, which supports long
# options. The "getopts" built-in to bash does not.
TEMP=$(getopt \
       -o 'hk:r:g:y:b:m:c:w:' \
       -l 'help,black:,red:,green:,yellow:,blue:,magenta:,cyan:,white:' \
       -n "$0" -- "$@")

if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi

eval set -- "$TEMP"

while true ; do
    case "$1" in
        -k|--bla*)       add_color_to_config blk "$2" ; shift 2 ;;
        -r|--red)        add_color_to_config red "$2" ; shift 2 ;;
        -g|--gre*)       add_color_to_config grn "$2" ; shift 2 ;;
        -y|--yel*)       add_color_to_config yel "$2" ; shift 2 ;;
        -b|--blu*)       add_color_to_config blu "$2" ; shift 2 ;;
        -m|--mag*)       add_color_to_config mag "$2" ; shift 2 ;;
        -c|--cya*)       add_color_to_config cya "$2" ; shift 2 ;;
        -w|--whi*)       add_color_to_config whi "$2" ; shift 2 ;;

        -h|--hel*)       usage ; exit 0 ;;

        --)         shift ; break ;;

        *)          echo 'Unknown option!' ; exit 1 ;;
    esac
done

spc -R -c "$CFGFILE" "$@"
rm -f "$CFGFILE"
    
por 29.08.2012 / 01:03
3

Incorporar strings arbitrárias (como tput output) em sed replace expression é problemático porque você precisa garantir (escapando) que a string é uma sintaxe sed válida, que é a melhor complexidade a ser evitada. Eu usaria awk em vez disso. Apenas como um exemplo:

{ echo line 1: PASS; echo line 2: FAIL; } | 
    awk -v "red=$(tput setaf 1)" -v "green=$(tput setaf 2)" \
        -v "reset=$(tput sgr0)" '
    { for (i = 1; i <= NF; i++) {
           if ($i == "FAIL") printf "%s", red "FAIL" reset;
           else if ($i == "PASS") printf "%s", green "PASS" reset;
           else printf "%s", $i

           if (i == NF) printf "%s", ORS
           else printf "%s", OFS 
      }}'

A chave é atribuir as sequências tput às variáveis awk , feitas aqui usando as opções -v .

    
por 29.08.2012 / 00:06
2

use printf:

printf "\e[%sm%s\e[00m\n" <some_number> <text_in_colour>

por exemplo,

printf "\e[%sm%s\e[00m\n" 32 yodle

o último \n adiciona o caractere de nova linha.

para ver possíveis valores de algo como:

for i in {0..9} {30..38} {90..98} {100..108};
do
    printf "%d:\e[%sm%s\e[00m\n" $i "$i" yodle;
done

Além da cor, você pode adicionar modificadores como negrito, sublinhado ou texto colorido com fundo colorido, combinando os números. Para criar texto em azul com fundo cinza que é sublinhado e destacado por meio do uso:

printf "\e[%sm%s\e[00m\n" "4;9;34;107" yodle

Felicidades,

/ B2S

    
por 30.08.2012 / 03:45
2

Se você estiver satisfeito em instalar um script BASH e ack , o pacote hhlighter tem cores padrão úteis e uma interface fácil link :

Você pode usá-lo assim para destacar as linhas que começam com FAIL :

h -i 'FAIL.*'

ou que contenham FAIL :

h -i '.*FAIL.*'

ou para várias entradas de registro comuns:

h -i '.*FAIL.*' '.*PASS.*' '.*WARN.*'

E, claro, para uma única cor (vermelho) com grep simples:

$ printf 'Pass: good job\nFail: bad job\n' | grep -Ei --colour=auto '^|fail.*'

O ^ corresponde a todas as linhas, mas é um combinador especial e imprime a linha inteira. A expressão a ser destacada é definida após um | . Outras expressões podem ser adicionadas contanto que sejam separadas por | .

    
por 01.04.2016 / 12:15