Shell-Script

如何通過重複呼叫配置顏色的函式來列印彩色日誌?

  • July 4, 2022

我想用另一種顏色的一些關鍵字列印日誌。以前我使用:

   cd ~/Code/Docker/somerepo && docker-compose logs -f my_service | grep -v "Successfully connected" | grep -v "this operation breaks ==" | sed "s/at com\.example\.product/at \x1b[32mcom\.example\.product\x1b[0m/g" | sed "s/caused by/\x1b[31mcaused by\x1b[0m/g"

作為一個函式,它可以工作。

現在我想提取顏色定義並將其放入名為get_colorand的函式中print_in_color

get_color() {
   number=
   case "$1" in
       RED)
       number='31'
       ;;
       GREEN)
       number='32'
       ;;
       YELLOW)
       number='33'
       ;;
       BLUE)
       number='34'
       ;;
       PURPLE)
       number='35'
       ;;
       *)
       number='38'
       ;;
   esac
   echo '\x1b['$number'm'
}

# $1 string, $2 color(RED, YELLOW, BLUE, GREEN, PURPLE)
print_in_color() {
   while read data;
   do
       color=$(get_color $2)
       nocolor='\x1b[0m'
       echo $1 | sed "s/$1/${color}$1${nocolor}/g"
   done;
}

並像使用它一樣

log_color() {
   cd ~/Code/Docker/somerepo && docker-compose logs -f my_service | grep -v "Successfully connected" | grep -v "this operation breaks ==" | print_in_color 'com\.example\.product' BLUE | print_in_color 'caused by' RED
}

但現在它只列印caused by紅色。

我如何定義一個函式來返回一個管道以管道到另一個函式?

只需簡化您的print_in_color功能:

print_in_color() {
   local -r LINE="${1//\//\\\/}"
   local -r color=$(get_color "$2")
   local -r nocolor='\x1b[0m'
   sed "s/\(${LINE}\)/${color}\1${nocolor}/g"

}

您不需要循環輸入數據。該sed命令接受管道輸入的數據並將結果寫入管道輸出,以便您可以連結許多print_in_color呼叫

更新

get_color功能:

#! /bin/bash

declare -g -r ANSI_CSI="\x1b["
declare -g -r ANSI_RESET="${ANSI_CSI}0m"
declare -g -r -A H_COLORS=(
   [RED]="${ANSI_CSI}31m"
   [GREEN]="${ANSI_CSI}32m"
   [YELLOW]="${ANSI_CSI}33m"
   [BLUE]="${ANSI_CSI}34m"
   [PURPLE]="${ANSI_CSI}35m"
   [OTHER]="${ANSI_CSI}38m"
)

# $1 string, $2 color(RED, YELLOW, BLUE, GREEN, PURPLE)
print_in_color() {
   local -r LINE="${1//\//\\\/}"
   local -r COLOR=${H_COLORS[${2:-OTHER}]}
   sed "s/\(${LINE}\)/${COLOR:-${H_COLORS[OTHER]}}\1${ANSI_RESET}/g"
}

引用自:https://unix.stackexchange.com/questions/708552