0%

sed中\1的用法

最近在看别人写的shell脚本时看到这样一个sed指令:

1
sed -i.bak -e's/\(LOBJS=.*\)/\1 bwtindex.o rle.o rope.o bwt.o is.o/g' bwa/Makefile

这里面使用了sed 's/要被取代的字符串/新的字符串/g' file的方式来对文本中指定的字符串进行全局替换,这里g代表的是global,之前面试又被问到过sed全局如何替换,当时就是忘记了最后应该要加/g,在这个命令中,新的字符串的内容中有一个\1之前从来没有遇到过,不知道具体的作用是什么,于是就去查找了一些资料进行学习。

在sed中,要被匹配的字符串可以用正则匹配来进行模式匹配,而用括号括起来的一个正则匹配串可以称为一个模式,而\1-9就是用来指代第一个、第二个、……、第九个模式在匹配到的字符串中的内容。在sed中一共可以记录9个模式,在某些需要保留原有字符串的一部分并添加一部分内容的时候就会很有用。

举个例子:

1
echo abc123 | sed 's/\([a-z]*\)\([0-9]{3}\)/\2\1/g'

这个例子的输出就是123abc,先来看下正则匹配的内容,一共有2个位于括号中的模式,第一个模式匹配的是出现次数任意多的小写字母,第二个模式匹配的是出现三次的数字,模式都用括号括起来,但是括号要使用反斜杠进行转义。在这个正则匹配中,\1代表的就是第一个模式匹配的内容,即abc,\2代表的是第二个模式匹配的内容,即123,然后替换成什么内容呢?就是交换这两个匹配的模式,把\2放到\1前面,就是123在前面,abc在后面,变成了123abc,就是这样简单,这是一个简单的交换匹配到的内容的例子,我们还可以在模式中插入内容,举例子来说:

1
echo abc123 | sed 's/\([a-z]*\)\([0-9]{3}\)/\1xx\2/g'

这个例子的输出就是在abc和123之间插入了两个字母xx,最终的结果是abcxx123,知道C当中的printf函数的同学可以把这里的\1\2理解成两个占位符,具体的内容由前面匹配到的模式的内容来进行填充,按照正则匹配中的顺序进行记录,最多记录9个。

这里在说一点题外话,sed -i我们知道是直接在原文件中进行修改,但是-i后面其实是可以加参数的,在最上面那个例子里面就是加了.bak作为-i的参数,这里的意思是,直接在原文件进行修改,但是将原文件保存为filename.bak,即在最后加上.bak进行备份。