语法格式
sed 有两种用法,对应的语法格式如下
stdout | sed [option] "pattern command"$ echo "hello world" | sed 'p'hello world
sed [option] "pattern command" file$ cat << EOF > hello.txt> hello world> EOF$ sed 'p' hello.txthello world
参数选项
-n : 只打印模式匹配行-e : 直接在命令行进行 sed 编辑,默认选项-f : 编辑动作保存在文件中,指定文件执行-r : 支持扩展正则表达式-i : 直接修改文件内容
-n
不加任何选项下,sed 在打印的时候,会默认将遍历到的行都打印出来
$ echo "I love Java" | sed 'p'I love JavaI love Java
可以加上 -n 选项,只打印匹配到的行
$ echo "I love Java" | sed -n 'p'I love Java
注意,替换的时候,不会打印出遍历到的行
$ echo "I love Java" | sed 's/love/like/'I like Java
-e
使用 -e 参数,可以在命令行中添加多个编辑命令
$ cat << EOF > sed.txt> I love Java> I love Python> I love scale> EOF$ sed -n -e '/Java/p' -e '/Python/p' sed.txtI love JavaI love Python
除了使用 -e 选项外,也可以通过将多个编辑命令使用 ; 分割的方式来达到同样的效果
$ sed -e '/Java/p;/Python/p' -n sed.txtI love JavaI love Python
-f
有时候 sed 的编辑命令会很复杂,直接把命令写在命令行终端会很长,不是很容易看,可以通过添加 -f 选项,读取文件文本作为编辑命令的方式来实现
$ cat << EOF > command.sed> /Java/p> EOF$ echo "I love Java" | sed -n -f command.sedI love Java
-r
一般情况下 sed 只能使用标准正则表达式,如果想让 sed 支持扩展正则表达式的话,需要加上 -r 参数
$ cat << EOF > sed.txt> I love Java> I love Python> I love scale> EOF$ sed -n '/Java|Python/p' sed.txt
上面示例,在执行完 sed 命令后,终端没有任何输出,这是因为 sed 把 Java|Python 当成一个整体去匹配了,如果想达到匹配 Java 或 Python 字符串的效果,需要加上 -r 参数,使其支持扩展正则表达式
$ cat << EOF > sed.txt> I love Java> I love Python> I love scale> EOF$ sed -n -r '/Java|Python/p' sed.txtI love JavaI love Python
-i
使用 sed 对文件进行操作的时候,默认不会修改文件的内容,如果想修改文件内容的话,可以加 -i 选项
$ cat << EOF > sed.txt> I love Java> I love Python> I love scale> EOF$ sed -i 's/love/like/' sed.txt$ cat sed.txtI like JavaI like PythonI like Scale
匹配模式
以下 sed 命令均使用下面文本进行演示
$ cat << EOF > sed.txt> I love Java> I love Python> I love scale> EOF
精确匹配行
精确匹配到某一行,可以通过直接指定行号的方式进行匹配
$ sed -n '2p' sed.txtI love Python
匹配从第几行~第几行
如果知道要匹配的行号是从第几行开始~第几行结束,可以直接指定两个行号,中间用 , 隔开
$ sed -n '1,2p' sed.txtI love JavaI love Python
匹配从第几行开始,往后多读几行
比如从第一行开始匹配,往后多读1行,即匹配1,2行
$ sed -n '1,+1p' sed.txtI love JavaI love Python
正则匹配
可以通过正则匹配,匹配需要处理的行。将正则表达式写在 // 中间即可
$ sed -n '/Java/p' sed.txtI love Java$ sed -n '/Ja.*/p' sed.txtI love Java
匹配pattern开始~pattern结束的行
$ sed -n '/Java/,/Python/p' sed.txtI love JavaI love Python
区间匹配
如果是想匹配一个区间的话,上面几种匹配模式可以混搭
$ sed -n '/Java/,+1p' sed.txtI love JavaI love Python$ sed -n '1,/Python/p' sed.txtI love JavaI love Python
编辑命令
p : 打印a : 行后追加i : 行前追加r : 外部文件读入,行后追加w : 匹配行写入外部文件d : 删除s/old/new/ : 替换第一个匹配到的字符串(old替换成new)s/old/new/g : 替换所有匹配到的字符串s/old/new/2g : 替换行内前两个字符串s/old/new/ig : 替换行内所有匹配到的字符串,忽略大小写
以下编辑命令的演示,均适用下面的数据进行演示
$ cat << EOF > sed.txt> I love Java> I love Python> I love scale> EOF
p
$ echo "hello" | sed -n 'p'hello
a
使用 a 编辑命令,在行后追加文本的时候,会换行
$ echo "hello" | sed 'a world'helloworld$ sed '/Java/a very much' sed.txtI love Javavery muchI love PythonI love Scale
i
同样的,使用 i 编辑命令,在行前追加文本的时候,也会新建新建一行
$ sed '/Java/i very much' sed.txtvery muchI love JavaI love PythonI love Scale
r
r 编辑命令其实跟 a 的作用相同,都是在行后追加文本,只不过 r 命令追加的文本内容是从外部文件读取,而 a 命令追加的文本是从命令行读取
$ cat << EOF > append.txt> this is append msg> EOF$ sed '/Java/r append.txt' sed.txtI love Javathis is append msgI love PythonI love Scale
w
w 作用是将匹配到的行信息写入到外部文件中,写入方式是覆盖写入,不是追加
$ echo "hello" | sed -n 'w test_w.txt'$ cat test_w.txthello$ sed -n '/Java/w test_w.txt' sed.txt$ cat test_w.txthello
d
d 删除命令,会删除匹配到的行,一般配合 -i 选项使用
$ sed '/Java/d' sed.txtI love PythonI love Scale$ sed '1d' sed.txtI love PythonI love Scale$ sed -i '/Java/d' sed.txt$ cat sed.txtI love PythonI love Scale
注意,使用 p 命令删除行的时候,一般不会加 -n 参数,加了 -n 参数往往会事与愿违
$ sed -i -n '1d' sed.txt$ cat sed.txt
上面示例,加上 -n 参数后, sed.txt 文本会被清空
s/old/new/
只会替换匹配到的第一个字符串
$ echo "I love Java so so so so much" | sed 's/so/aaa/'I love Java aaa so so so much
s/old/new/g
想要替换匹配到的所有字符串,可以使用 s/old/new/g
$ echo "I love Java so so so so much" | sed 's/so/aaa/g'I love Java aaa aaa aaa aaa much
s/old/new/2g
从匹配到的第 n 个字符串开始替换
$ echo "I love Java so so so so much" | sed 's/so/aaa/2g'I love Java so aaa aaa aaa much$ echo "I love Java so so so so much" | sed 's/so/aaa/3g'I love Java so so aaa aaa much
s/old/new/ig
$ echo "I love Java so so so so much" | sed 's/So/aaa/ig'I love Java aaa aaa aaa aaa much
可以将 s/old/new/2g 跟 s/old/new/ig 这两种匹配模式合起来一起用
echo "I love Java so so so so much" | sed 's/So/aaa/i2g'I love Java so aaa aaa aaa muchecho "I love Java so so so so much" | sed 's/So/aaa/2ig'I love Java so aaa aaa aaa much
方向引用
& : 引用匹配模式匹配到的整个字符串\n : 引用匹配模式匹配到的第n个字符串
&
$ sed 's/love \(.*\)/& very much/' sed.txtI love Java very muchI love Python very muchI love scale very much
\n
使用 \n 可以引用匹配到的第几个字符串,使用 \n 的时候,要匹配的字符串必须用 () 括起来
$ sed 's/love \(.*\)/\1 very much/' sed.txtI Java very muchI Python very muchI scale very much# 将两个文本调换位置$ sed 's/\(love\)\(.*\)/\2 \1/' sed.txtI Java loveI Python loveI scale love
