我有两个命令perl
和一个测试文件test.txt
:
$ cat test.txt
aaa bla
bbb foo
#ccc bar
ddd 444
第一个perl
表达式将任何出现的aaa
或bbb
红色着色:
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"
现在我需要将这两个表达式合并为一个,具有以下属性:
如果行以 开头#
,则使用绿色对整行进行着色。如果行不以#
着色任何出现的红色aaa
或bbb
使用红色开始。
换句话说,如果行已经是绿色的(即典型的;注释行),我不想为任何可能出现的aaa
or着色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”位于行上相同的线,不会的。
最后,看起来你正在重新发明轮子。已经存在多种用于为文本着色的工具。这强调例如,工具。它主要用于源代码的语法突出显示,但也可用于为任何类型的文本着色。