我准备了一个文件Hello.txt,如下所示。
1253125213
213532135
23513125215
然后,我想将除“2”之外的每行都着色为蓝色,并将“2”着色为红色。
一开始,我写了
BLUE='\033[0;34m'
RED='\033[0;31m'
并尝试这样做sed 's/2/${RED}2${BLUE}/'
,但这行不通。
我该怎么做呢?
答案1
首先,插值时需要双引号:
$ sed "s/2/${RED}2${BLUE}/" Hello.txt
1233[0;31m2233[0;34m53125213
233[0;31m2233[0;34m13532135
233[0;31m2233[0;34m3513125215
但是,ASCII 转义序列包含影响 sed 的字符,因此您必须将转义字符序列转换为实际的控制字符。这可以通过使用子 shell 来完成。请注意最后的/g
,这意味着每行允许多次替换。
$ sed "s/2/`echo $RED`2`echo $BLUE`/g" Hello.txt
现在看来,这仍然不太正确。我们真正应该做的是将每条线设置为蓝色开始,然后使每个2
替换开始红色并结束蓝色。帽子字符^
是正则表达式,表示行的开头。还要注意管道的使用和重新排列cat
。
$ cat Hello.txt | sed "s/^/`echo $BLUE`/" | sed "s/2/`echo $RED`2`echo $BLUE`/g"
您还可以通过将子 shell 转换移至变量赋值来使其更清晰。需要大括号,以便RED
将其与2
字符区分开,这样它就不会尝试使用不存在的变量RED2
。
$ BLUE=`echo '\033[0;34m'`
$ RED=`echo '\033[0;31m'`
$ cat Hello.txt | sed "s/^/$BLUE/" | sed "s/2/${RED}2${BLUE}/g"
来源:http://www.cyberciti.biz/faq/unix-linux-sed-ascii-control-codes-nonprintable/
答案2
正如 ZimbiX 已经解释的那样,使用双引号等。
他的方法的替代方法是使用$'…'
转义序列被解释的语法。 IE:
\e => ASCII ESC (0x1b, 033)
\033 => ASCII ESC (0x1b, 033)
\x1b => ASCII ESC (0x1b, 033)
所以:
red=$'\e[31m'
blue=$'\e[34m'
然后:
printf $blue && sed "s/2/${red}2$blue/g" Hello.txt
或者,如果您愿意,请包括重置多变的:
cc=$'\e[0m'
printf $blue && sed "s/2/$cc${red}2$cc$blue/g" Hello.txt && printf $cc
要查看代码,请输入以下内容:
(printf $blue && sed "s/2/${red}2$blue/g" Hello.txt) | cat -v
g
另请注意for global in的使用sed
。