คุณจะปรับสีคำหลักบางคำสำหรับสคริปต์ทุบตีได้อย่างไร


10

ฉันใช้รหัสการทดสอบหน่วย โค้ดทดสอบหน่วยจะแสดงข้อความปกติ มีข้อความจำนวนมากดังนั้นฉันต้องการเน้นสำหรับคำหลักที่สำคัญของผู้ใช้

ในกรณีนี้คำหลักคือ "PASS" และ "FAIL"

คุณเปลี่ยนสี "PASS" เป็นสีเขียวและ "FAIL" เป็นสีแดงได้อย่างไร


คุณคิดเกี่ยวกับการหยุด stdout / stderr ของการทดสอบที่ผ่านไปแล้วและพิมพ์ stdout / stderr สำหรับการทดสอบที่ล้มเหลวเท่านั้น PHPUnit ทำสิ่งนี้หรือกำหนดให้ทำเช่นนี้ได้ ฉันพบว่าวิธีนี้ใช้งานได้ดีทีเดียว YMMV
Clayton Stanley เมื่อ

คำตอบ:


8

supercat ดูเหมือนจะทำสิ่งที่คุณกำลังมองหา

แพ็คเกจ: supercat
คำอธิบาย - en: โปรแกรมที่ colorizes ข้อความสำหรับอาคารและ HTML
 Supercat เป็นโปรแกรมที่เปลี่ยนสีข้อความตามการจับคู่แบบปกติ
 การแสดงออก / สตริง / ตัวอักษร Supercat รองรับเอาต์พุต HTML เช่นกัน
 เป็นข้อความ ASCII มาตรฐาน ไม่เหมือนกับโปรแกรมเปลี่ยนสีข้อความบางโปรแกรมที่
 มีอยู่ Supercat ไม่ต้องการให้คุณเป็นโปรแกรมเมอร์
 ทำกฎ colorization
โฮมเพจ: http://supercat.nosredna.net/

ดูเหมือนจะไม่มีวิธีใดที่จะบอกได้ว่าจะให้สีอะไรบนบรรทัดคำสั่งคุณต้องระบุไฟล์ปรับแต่ง

ฉันดูเหมือนจะจำได้ว่าเคยเป็นโปรแกรมที่เรียกว่า 'ไฮไลต์' หรือ 'hl' ที่ไฮไลต์ข้อความที่ตรงกับรูปแบบ (เช่นgrep --colourแต่แสดงบรรทัดที่ไม่ตรงกันเช่นกัน) แต่ฉันไม่พบมันเมื่อฉันค้นหา

ในที่สุด GNU grepสามารถใช้เพื่อเน้นรูปแบบ - แต่สามารถใช้เพียงหนึ่งสีเท่านั้น (เช่นคุณไม่สามารถผ่าน PASS ในสีเขียวและ FAIL เป็นสีแดงทั้งสองจะถูกเน้นด้วยสีเดียวกัน)

ไพพ์ข้อมูลของคุณผ่านบางสิ่งเช่นนี้:

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

ตัวอย่างนี้ใช้ egrep (aka grep -E) แต่-Gregexp พื้นฐาน-Fสตริงคงที่และ-PPCRE ก็ใช้ได้เช่นกัน

การแข่งขันทั้งหมดจะถูกเน้น ค่าเริ่มต้นคือสีแดงหรือตั้งค่า GREP_COLOR env var

กุญแจสำคัญของการทำงานนี้คือ|$รูปแบบสุดท้ายตรงกับจุดสิ้นสุดของบรรทัด (เช่นทุกบรรทัดตรงกัน) ดังนั้นทุกบรรทัดจะปรากฏขึ้น (แต่ไม่ใช่สี)

\bเครื่องหมายคำเขตแดนเพื่อให้ตรงเช่น FAIL แต่ไม่ล้มเหลว ไม่จำเป็นต้องลบออกหากคุณต้องการจับคู่คำบางส่วน

นี่คือตัวอย่างของสคริปต์ wrapper สำหรับ 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คุณสามารถปรับเปลี่ยนสคริปต์ที่คุณโพสต์ในการสร้างไฟล์ config ชั่วคราวขึ้นอยู่กับ args spc -c /path/to/your/temp/configบรรทัดคำสั่งแล้วโทร สิ่งนี้จะช่วยให้คุณสามารถระบุสีที่แตกต่างสำหรับรูปแบบที่แตกต่างกันในบรรทัดคำสั่ง
cas

ยัง btw ฉันเขียนสคริปต์ wrapper ง่าย ๆ ที่จะทำ ฉันต้องมุ่งหน้าไปทำงานตอนนี้ แต่ฉันจะทำความสะอาดเพิ่มความคิดเห็น ฯลฯ และโพสต์ในภายหลังวันนี้
cas.

5

นี่คือสคริปต์ที่ใช้งานทั่วไปเพื่อทำให้รูปแบบ regex เป็นสี (อาจต้องรีทัชบางส่วน):

#! /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เพราะโซลูชันของฉันไม่ทำงาน
เทรเวอร์บอยด์สมิ ธ

วิธีง่ายๆในการทดสอบคือการสร้างสคริปต์อื่นที่สะท้อนข้อความด้วยคำหลัก "PASS" และ "FAIL" จากนั้นสคริปต์นี้จะถูกเรียกใช้
เทรเวอร์บอยด์สมิ ธ

ปิดหัวข้อเล็กน้อย แต่ฉันต้องชี้ให้เห็นว่าการแยกเอาต์พุตของการส่ง$BINผ่านevalไปยังการทดแทนคำสั่งอาจเป็นไปได้ว่าเปราะบางยุ่งยากและอันตรายอย่างยิ่ง STDOUT เป็นสตรีมและโดยทั่วไปหมายถึงการประมวลผลโดยสตรีมเช่นเครื่องมือ การพยายามจับกระแสทั้งหมดในตัวแปรนั้นไม่ได้มีประสิทธิภาพมากนัก นอกจากนี้ยังevalมีพลังอันตรายดังนั้นให้ใช้เฉพาะเมื่อคุณรู้ว่าคุณกำลังทำอะไรอยู่
jw013

ฉันแทนที่สคริปต์ด้วยอันที่ทำงานได้
กัส

@angus สคริปต์ IMO ที่ดีและน่าประทับใจจริงๆ
เทรเวอร์บอยด์สมิ ธ

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ตัวเลือก


ฉันรันโปรแกรมของคุณและทำสิ่งที่จำเป็น Huzzah! แต่น่าเสียดายที่ฉันไม่ใช่กูรู awk ดังนั้นฉันจึงพบว่ามันยากที่จะเข้าใจสิ่งที่เกิดขึ้น แก้ไขฉันในที่ที่ฉันผิด มีการรัน awk บรรทัดใหม่แต่ละรายการหรือไม่ การวนซ้ำในซอร์สโค้ด awk กำลังดำเนินการ: "สำหรับโทเค็นทั้งหมดในบรรทัด" หรือไม่ มันจะประมวลผลแต่ละโทเค็นหรือไม่
เทรเวอร์บอยด์สมิ ธ

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

หากคุณมีความสุขในการติดตั้งสคริปต์ทุบตีและackการhhlighterแพคเกจมีสีเริ่มต้นที่มีประโยชน์และมีอินเตอร์เฟซง่ายhttps://github.com/paoloantinori/hhighlighter :

ตัวอย่าง hhighlight

คุณสามารถใช้มันเพื่อเน้นแถวที่ขึ้นต้นด้วย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.*'

การ^จับคู่ทุกบรรทัด แต่เป็น matcher พิเศษและพิมพ์ทั้งบรรทัด |การแสดงออกที่จะมีการเน้นถูกกำหนดหลังจากที่ |การแสดงออกเพิ่มเติมสามารถเพิ่มตราบเท่าที่พวกเขากำลังแยกด้วย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.