bash 스크립트의 일부 키워드 만 어떻게 채색합니까?


10

단위 테스트 코드를 실행 중입니다. 단위 테스트 코드는 일반 텍스트를 출력합니다. 많은 텍스트가 있으므로 사용자에게 중요한 키워드를 강조하고 싶습니다.

이 경우 키워드는 "PASS"및 "FAIL"입니다.

"PASS"를 녹색으로, "FAIL"을 빨강으로 어떻게 채색합니까?


통과 한 테스트의 stdout / stderr을 억제하고 실패한 테스트에 대해서만 stdout / stderr를 인쇄하는 것에 대해 생각해 보셨습니까? PHPUnit이이를 수행하거나 구성 할 수 있습니다. 이 접근 방식이 YMMV에서 잘 작동한다는 것을 알았습니다.
Clayton Stanley

답변:


8

supercat 당신이 찾고있는 것을하는 것 같습니다.

패키지 : 슈퍼 캣
Description-en : 터미널 및 HTML의 텍스트를 색칠하는 프로그램
 Supercat은 일치하는 규칙에 따라 텍스트를 채색하는 프로그램입니다
 표현식 / 문자열 / 문자. Supercat은 html 출력도 지원합니다
 표준 ASCII 텍스트로. 일부 텍스트 채색 프로그램과 달리
 Supercat은 프로그래머가 아니어도됩니다.
 착색 규칙을 만듭니다.
홈페이지 : http://supercat.nosredna.net/

커맨드 라인에서 무엇을 채색 할지를 알 수있는 방법이없는 것 같습니다. 설정 파일을 지정해야합니다.

패턴과 일치하는 텍스트를 강조 표시하는 (hilite) 또는 'hl'이라는 프로그램이 grep --colour있었지만 (예 를 들어 일치하지 않는 행도 표시) 프로그램을 검색했을 때 찾을 수 없었습니다.

마지막으로 GNU grep를 사용하여 패턴을 강조 할 수 있습니다. 단 하나의 색상 만 사용할 수 있습니다 (즉, 녹색으로 통과 및 빨간색으로 실패 할 수 없으며 둘 다 동일한 색상으로 강조 표시됨).

다음과 같이 데이터를 파이프하십시오.

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

이 예제는 egrep (aka grep -E)를 사용하지만 -G기본 정규 표현식, -F고정 문자열 및 -PPCRE도 작동합니다.

모든 경기가 강조 표시됩니다. 기본값은 빨간색이거나 GREP_COLOR env var를 설정합니다.

이 작업의 핵심 |$은 패턴 의 마지막 부분이 줄 끝과 일치하므로 모든 줄이 일치하므로 모든 줄이 표시되지만 색상이 표시되지는 않습니다.

\b이 예를 들어 FAIL하지만 실패 일치하도록 단어 경계 마커입니다. 그것들은 필요하지 않으므로 부분 단어와 일치 시키려면 제거하십시오.

다음은 어제 작성한 supercat의 래퍼 스크립트 예제입니다. 작동하지만 서면으로 supercat에 대소 문자를 구분하지 않는 검색 옵션이 없음을 발견했습니다. IMO는 프로그램의 유용성을 떨어 뜨립니다. 그러나 '-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"

1
BTW, 사용한 경우 supercat명령 줄 인수를 기반으로 임시 구성 파일을 생성하도록 게시 한 스크립트를 수정 한 다음을 호출 할 수 spc -c /path/to/your/temp/config있습니다. 이를 통해 명령 행에서 다른 패턴에 대해 다른 색상을 쉽게 지정할 수 있습니다.
cas

또한 btw, 나는 간단한 래퍼 스크립트를 작성했습니다. 지금 일하러 가야하지만 정리하고 주석을 추가하고 오늘 나중에 게시 할 것입니다.
cas

5

다음은 정규식 패턴을 채색하는 범용 스크립트입니다 (아마도 일부 수정이 필요함).

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

이름을 지정하고 다음 hilite.sh과 같이 사용하십시오.

$ ./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

community wiki내 솔루션이 작동하지 않기 때문에 이것을 만들었습니다 .
Trevor Boyd Smith

테스트하는 쉬운 방법은 키워드 "PASS"및 "FAIL"로 텍스트를 표시하는 다른 스크립트를 만드는 것입니다. 그런 다음이 스크립트에 의해 호출됩니다.
Trevor Boyd Smith

주제를 약간 벗어 났지만 $BIN비아 의 출력 eval을 명령 대체로 파싱하는 것은 아마도 깨지기 쉽고 번거롭고 완전히 위험하다는 것을 지적해야합니다. STDOUT은 스트림이며 일반적으로 스트림과 같은 도구로 처리됩니다. 변수에서 전체 스트림을 캡처하는 것은 그리 효율적이지 않습니다. 또한 eval매우 강력 하므로 실제로 수행중인 작업을 알고있는 경우에만 사용하십시오.
jw013

스크립트를 작동하는 것으로 교체했습니다.
angus

@angus, 정말 훌륭하고 인상적인 스크립트 IMO.
Trevor Boyd Smith

3

대체 표현식에 tput출력 과 같은 임의의 문자열을 포함 sed시키는 것은 문제가됩니다. 이스케이프하여 문자열이 유효한 sed구문 인지 확인해야하므로 피하는 것이 더 복잡합니다. awk대신에 사용하겠습니다 . 예를 들어 :

{ 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 
      }}'

핵심은 옵션을 사용하여 tput시퀀스에 awk변수 를 할당하는 것 -v입니다.


나는 당신의 프로그램을 실행했고 필요한 일을합니다. 후자! 그러나 불행히도 나는 어색한 전문가가 아니므로 무슨 일이 일어나고 있는지 이해하기가 어렵습니다. 내가 틀린 곳을 바로 잡으십시오. 각 줄마다 awk가 실행됩니까? awk 소스 코드의 for 루프는 다음과 같습니다 : "라인의 모든 토큰"? 그런 다음 각 토큰을 처리합니까?
Trevor Boyd Smith

Awk는 필드와 레코드의 관점에서 생각합니다. 기본적으로 레코드는 텍스트 줄이며 필드는 공백이 아닙니다. awk스크립트 블록 세트 (사이의 재료로 구성되어 {}최고 수준). 각 블록은 조건과 관련이 있습니다. 위의 게시물에는 모든 입력 줄에 무조건적으로 행동하기를 원하는 것이 없습니다. Awk는 파일 또는 표준 입력 (이 경우 STDIN b / c 파일 이름이 제공되지 않음)에서 레코드를 읽고 모든 블록에 대해 순서대로 일치시켜 조건에 일치하는 경우 레코드에서 블록을 실행합니다.
jw013

2

printf를 사용하십시오 :

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

예.

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

마지막 \n줄 바꿈 문자를 추가합니다.

시도의 가능한 값을 보려면 다음과 같이하십시오.

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

색상 외에도 숫자를 결합하여 굵은 체 또는 밑줄 또는 컬러 배경의 컬러 텍스트와 같은 수정자를 추가 할 수 있습니다. 밑줄이 그어진 회색 배경의 파란색 텍스트를 작성하려면 다음을 사용하십시오.

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

건배,

/ B2S


2

BASH 스크립트를 설치 ack하고 hhlighter패키지에 유용한 기본 색상과 편리한 인터페이스가 https://github.com/paoloantinori/hhighlighter :

하이라이트 예

이렇게 사용하여 FAIL다음으로 시작하는 행을 강조 표시 할 수 있습니다 .

h -i 'FAIL.*'

또는 다음을 포함합니다 FAIL:

h -i '.*FAIL.*'

또는 다양한 공통 로그 항목의 경우 :

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

물론 일반 grep이있는 단색 (빨간색)의 경우 :

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

^모든 라인을 일치하지만 특별한 정규이며, 전체 라인을 인쇄합니다. 강조 표시 할 표현식은 다음에 정의됩니다 |. 로 구분되는 한 추가 표현식을 추가 할 수 있습니다 |.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.