今天继续介绍Linux三剑客中的sed
sed是stream editor(流编辑器)的缩写。它最常见的用法是进行文本替换。下面介绍一些sed的常见用法。
sed最常见的功能,是用它进行文本替换。它的替换形式和vim非常相似,具体语法如下:
$ sed 's/pattern/replace_string/' file
其中pattern代表替换用的模式串,replace_string代表被替换的字符串。sed命令不改变原有的文件,如果想要直接替换原来的文件, 需要使用-i选项。
$ sed -i 's/text/replace/' file
前面的例子只能替换了每行中模式首次匹配的内容。要实现全局替换必须使用g标记。
$ sed 's/pattern/replace_string/g' file
/#g标记可以使sed替换第N次出现的匹配:
$ echo thisthisthisthis | sed 's/this/THIS/2g' thisTHISTHISTHIS $ echo thisthisthisthis | sed 's/this/THIS/3g' thisthisTHISTHIS $ echo thisthisthisthis | sed 's/this/THIS/4g' thisthisthisTHIS
sed还可以用来对文本进行处理,例如删除空行。行可以用正则表达式 ^$ 进行匹配,用/d告诉sed不执行替换操作,而是直接删除匹配到的空行。
$ sed '/^$/d' file
注意这里开头没有s。
在sed中,我们可以用&指代模式所匹配到的字符串,这样就能够在替换字符串时使用已匹配的内容。例如下面这个例子:
$ echo this is an example | sed 's/\w\+/[&]/g' [this] [is] [an] [example]
&指代匹配给定模式的字符串。我们还可以使用\#来指代出现在括号中的部分正则表达式(注:子模式)所匹配到的内容:
$ echo this is digit 7 in a number | sed 's/digit \([0-9]\)/\1/' this is 7 in a number
这条命令将digit 7替换为7。\(pattern\)用于匹配子串,在本例中匹配到的子串是7。子模式被放入使用反斜线转义过的()中。对于匹配到的第一个子串,其对应的标记是\1,匹配到的第二个子串是\2,往后以此类推。我们还可以对这些匹配到的子串进行处理。
$ echo seven EIGHT | sed 's/\([a-z]\+\) \([A-Z]\+\)/\2 \1/' EIGHT seven
上面这条命令中,\1匹配得到单词seven,\2匹配得到单词\EIGHT。在替换部分,它们的次序被更改为\2 \1,因此就呈现出了逆序的结果。
sed可以组合多个表达式来对文本进行替换,有三种表示方法:
$ sed 'expression' | sed 'expression' # 第一种 $ sed 'expression; expression' #第二种 $ sed -e 'expression' -e 'expression' # 第三种
它们使用的效果是相同的。
$ echo abc | sed 's/a/A/' | sed 's/c/C/' AbC $ echo abc | sed 's/a/A/;s/c/C/' AbC $ echo abc | sed -e 's/a/A/' -e 's/c/C/' AbC
另外,在sed的表达式中可以使用变量,这时需要使用双引号。
$ text=hello $ echo hello world | sed "s/$text/HELLO/" HELLO world