使用 Perl 表达式进行条件着色

使用 Perl 表达式进行条件着色

我有两个命令perl和一个测试文件test.txt

$ cat test.txt
aaa bla
bbb foo
#ccc bar
ddd 444

第一个perl表达式将任何出现的aaabbb红色着色:

cat test.txt | perl -pe "s/(aaa|bbb)/\e[1;31m\1\033[0m/g"

第二个表达式将所有以 开头的行着色为绿色#

cat test.txt | perl -pe "s/^(#.*)/\e[0;32m\1\033[0m/g"

现在我需要将这两个表达式合并为一个,具有以下属性:

如果行以 开头#,则使用绿色对整行进行着色。如果行不以#着色任何出现的红色aaabbb使用红色开始。

换句话说,如果行已经是绿色的(即典型的;注释行),我不想为任何可能出现的aaaor着色bbb。否则,我想把它们染成红色。

我如何结合我的两个表达式来实现这一目标?

答案1

最简单的方法是:

cat test.txt | perl -pe "s/^(#.*)/\e[0;32m\1\033[0m/g || s/(aaa|bbb)/\e[1;31m\1\033[0m/g"

这使用逻辑或运算符||告诉 perl 仅s///在第一个失败时运行第二个。即类似于if (/#/) ... else if (/aaa|bbb/) ...

|| s///如果需要,您可以在脚本末尾添加更多内容,但如果您需要搜索和着色许多更多的比赛,如果把它当作一句台词来做,就会变得太复杂了。在这种情况下,将整个脚本重写为一个独立的#! /usr/bin/perl -p脚本,也许每行一个s///g ||,最后一个分号而不是||最后一行。

例如:

#! /usr/bin/perl -p

s/^(#.*)/\e[0;32m\1\033[0m/g ||
s/(aaa|bbb)/\e[1;31m\1\033[0m/g || 
s/(ccc)/\e[1;34m\1\033[0m/g ;

请注意,这样做意味着在任何给定行上只能找到一个匹配项,并且第一个匹配项获胜。因此,在上面的较长脚本示例中,如果在一行上找到“aaa”或“bbb”,那么它们将被着色,但如果“ccc”位于行上相同的线,不会的。

最后,看起来你正在重新发明轮子。已经存在多种用于为文本着色的工具。这强调例如,工具。它主要用于源代码的语法突出显示,但也可用于为任何类型的文本着色。

相关内容