一米豆芽 阅读(71) 评论(0)

在sed命令中有许多的字符都被转义,比如\ , $, ^,单双引号还有点号等等,因此使用sed命令进行字符串的匹配和修改的时候,字符串中如果含有转义字符,很多情况下不能直接用字符本身表示。这时候可以使用反斜杠加上转义字符的方法来输出含转义字符的字符串,但这一方法并不是对所有的转义字符都有用,过程也较复杂。下面一一说明:

一般而言sed命令格式由三部分组成,sed + 功能选项 + 条件选项,功能选项由连接符号-加上代表不同功能的字母构成,条件选项表明对文本的筛选和处理条件,一般括在单引号或者双引号中。但两种引号在sed命令处理的过程中略有不同:
单引号:对其中的内容不做任何处理,即引号内的内容是sed命令定义的格式,对于在条件选项中使用的转义字符需要使用反斜杠加转义字符才能输出。例如:
若定义变量 temp=/home/test/, var=aa
>echo $temp | sed 's/\//$var/g'
输出结果为:$varhome$vartest$var
你可能会发现并不是所有的转义字符都需要加反斜杠来输入(如上例中的$符号),这取决于转义字符在条件选项中的位置,如果在这个位置字符本身转义起作用,则需要加反斜杠。即sed命令先检查字符转义功能是否成立,若有转义功能则使用转义功能,否则按字符输出。如果你想要输出该字符时不确定该字符是否会转义,可以对所有位置添加反斜杠。

双引号:会对其中的变量进行直接转换,同样是上例,如果写成:
>echo $temp | sed “s/\//$var/g”
则输出结果为:aahomeaatestaa
可以看出双引号将变量名直接替换成变量内容。

要想使用单引号得到上面双引号的输出结果也是可以做到的,这时候需要对变量名加单引号来处理:
>echo $temp | sed 's/\//'$var'/g'
同样可以得到输出结果为:aahomeaatestaa

对于sed命令,如上例单引号命令>echo $temp | sed 's/\//$var/g' 中,我们对斜杠符号的输出加上了反斜杠,以免被sed命令视为转义字符功能。我们还可以采用另一种方法无需使用加反斜杠来输出斜杠字符。在这个命令中,分隔符使用了斜杠(/),因此斜杠默认转义,sed中是可以使用其他符号作为分隔符的,如果不使用斜杠作为分隔符,则斜杠默认无转义功能,这时就不需要借助反斜杠来输出了:
>echo $temp | sed 's#/#'$var'#g'
这里我们使用#来代替/当分隔符,因此/不再具有转义功能,无需再加反斜杠来辨识。同样可以得到上面的输出效果。分隔符对单引号和双引号作用一样。

若字符串中含有单引号,有的时候会发现加反斜杠还是得不到想要的字符串输出。比较简单的一个做法是字符串中有单引号时,功能选项部分用双引号括起来,这样不用加反斜杠可以直接输出字符。例如:
>echo $temp | sed "s#/#'#g"
输出结果为:'home'test'
同理上例如果写成:>echo $temp | sed 's#/#\'#g',则会报错。因为单引号需要成对出现,否则sed命令无法知道第一个单引号究竟与第二个还是第三个单引号匹配。

若字符串中含有双引号时,功能选项部分用单引号括起来,也可以不使用反斜杠来输出双引号。
>echo $temp | sed 's#/#"#g'
输出结果为:"home"test"
但是,与单引号不同的是,上例如果写成:>echo $temp | sed "s#/#\"#g",却不会报错。这也就很好的解决了如果字符串中同时有单双引号的时候该如何处理的问题。

在更加复杂的文本情况中,sed命令中的转义字符还有许多问题需要注意,需要根据具体情况采取不同的输出方法来解决问题。