彩色输出取决于用户定义的图案

彩色输出取决于用户定义的图案

我有兴趣编写一个 bash 函数来打印变量的内容并突出显示与给定模式匹配的所有行。

以下用于awk处理变量中的行。但这不适用于匹配模式,而是通过指定要着色的行(例如 lseq="2,3,5")。

aid ()
 {  
  local -r sgr="$( tput sgr0 )"  
  local -r blu="$( tput bold; tput setaf 39 )"
  
  awk -v frg="$blu" -v rst="$sgr" -v lnum="$lseq" ptrn="$rl" \
    'BEGIN { split(lnum, laggr, ",") }
      {
       found = 0
       for (item in laggr) {
         if (laggr[item] == NR) { found = 1 ; break }
        }
       if (found) { print frg $0 rst }
       else { print $0 }
      }' <<< "$@"
 }

例如,我有以下多行变量,我想在其中打印以edvart使用蓝色前景开头的行。

rl="^[[:space:]]*edvart .*$"
var="
Here is an example
  edvart -W
Some description
Introduction
Menu
Interactive"

答案1

以下是解决该问题的主要要素:

  1. 用于tput着色
  2. 将源文本放入管道中
  3. 处理线条

while这是使用/ 的解决方案read

rst=$( tput sgr0 ) ; hi=$( tput bold; tput setaf 39 )

printf '%s\n' "$source" \
| while read line
do
  if [[ "$line" =~ "$pattern" ]]; then
    printf '%s\n' "${hi}${line}${rst}"
  else
    printf '%s\n' "$line"
  fi
done

请注意,该=~语法特定于 bash。可以grep在 if 语句中使用它并利用其退出状态,但我不会在这里显示这一点,因为您用“bash”标记了问题。

这是一个解决方案awk

rst=$( tput sgr0 ) ; hi=$( tput bold; tput setaf 39 )
printf '%s\n' "$source" \
| awk '{
  if ( $0 ~ /'"$pattern"'/ ) {
    printf "'${hi}'%s'${rst}'\n", $0
  } else {
    print
  }
}'

另一个解决方案是sed

rst=$( tput sgr0 ) ; hi=$( tput bold; tput setaf 39 )
printf '%s\n' "$source" | sed "/$pattern/s/^.*$/${hi}&${rst}/"

对于awksed,我在技术上将颜色/格式嵌入到 awk/sed 脚本中。所以实际上不需要hi和变量。rst但我认为它更容易阅读。

awk和解决方案sed比 解决方案更具可移植性read,可在任何 POSIX 兼容系统上运行。

如果您只想突出显示匹配的字符串而不是整行,我建议使用sed.

rst=$( tput sgr0 ) ; hi=$( tput bold; tput setaf 39 )
printf "$source" | sed "s/$pattern/${hi}&${rst}/g"

相关内容