我有一个多行字符串,用于在 bash 脚本中打印。
docstring="
Headings
-H, -H CNT, -H=CNT, -HCNT, --heading CNT, --heading=CNT
Warnings
-W, -W CNT, -W=CNT, -WCNT, --warning CNT, --warning=CNT
Errors
-E, -E CNT, -E=CNT, -ECNT, --error CNT, --error=CNT"
echo "$docstring"
我想创建一个函数,它接受这个字符串并以颜色打印以-
or开头的行{-
。
因此,下面的内容将被着色
-H, -H CNT, -H=CNT, -HCNT, --heading CNT, --heading=CNT
-W, -W CNT, -W=CNT, -WCNT, --warning CNT, --warning=CNT
-E, -E CNT, -E=CNT, -ECNT, --error CNT, --error=CNT
答案1
使用 GNU 的一种方法sed,假设字符串不包含\
, `
,"
也不$
包含字符:
printred(){
sed -E 's/^ *\{?-.*/tput setaf 1;printf "%s" "&";tput sgr0/e' <<< "$@"
}
用法:
printred "$docstring"
要选择其他颜色,请检查:
for i in {0..7}; do
tput setaf "$i"
echo "tput setaf $i"
tput sgr0
done
注意事项:
不要按原样用作 CGI 脚本,请将其保留为私有,因为正如 Stephane Chazelas 所指出的,您可以运行任意命令。这是为了在受信任的环境中使用。或者制作一种过滤器来清理输入字符串
答案2
与 GNU 实现grep
或兼容:
grep --color -Ee '^\s*\{?-.*' -e '^' <<< "$docstring"
这是grep
ping 以任意数量的空白字符开头的行,后跟一个可选字符,{
后跟-
任意数量的字符,或者只是行的开头,只要输出到达终端设备(假设它显示),就会对匹配的内容进行着色在终端上,解释这些转义序列的那些)。--color=always
即使输出未发送到终端设备,也可以更改为添加着色。
使用哪些属性和颜色(默认为粗体红色)是通过$GREP_COLORS
环境变量(以前的$GREP_COLOR
)控制的。
grep
例如,GREP_COLORS='mt=1;41;33' grep...
将m
附加的分机调用t
为粗体、黄色前景、红色背景。
printred
以红色打印匹配行的函数可能如下所示:
println() { # prints each of its arguments on separate lines
[ "$#" -eq 0 ] || printf '%s\n' "$@"
}
printred() {
println "$@" |
GREP_COLORS='mt=31' grep --color -Ee '^\s*\{?-.*' -e '^'
}
另一种不依赖 GNUisms 来突出显示这些行的方法是sed
在匹配行周围添加 ANSI 转义序列:
ESC=$(printf '\33')
printred() {
if [ -t 1 ]; then
println "$@" |
sed "s/^[[:space:]]*{\{0,1\}-.*/${ESC}[31m&${ESC}[m"
else
println "$@"
}
或者perl
代替sed
:
perl -pe 's/^\s*\{?-.*/\e[31m$&\e[m/'