语法格式

sed 有两种用法,对应的语法格式如下

  • stdout | sed [option] "pattern command"

    1. $ echo "hello world" | sed 'p'
    2. hello world
  • sed [option] "pattern command" file

    1. $ cat << EOF > hello.txt
    2. > hello world
    3. > EOF
    4. $ sed 'p' hello.txt
    5. hello world

参数选项

-n : 只打印模式匹配行
-e : 直接在命令行进行 sed 编辑,默认选项
-f : 编辑动作保存在文件中,指定文件执行
-r : 支持扩展正则表达式
-i : 直接修改文件内容

-n

不加任何选项下,sed 在打印的时候,会默认将遍历到的行都打印出来

  1. $ echo "I love Java" | sed 'p'
  2. I love Java
  3. I love Java

可以加上 -n 选项,只打印匹配到的行

  1. $ echo "I love Java" | sed -n 'p'
  2. I love Java

注意,替换的时候,不会打印出遍历到的行

  1. $ echo "I love Java" | sed 's/love/like/'
  2. I like Java

-e

使用 -e 参数,可以在命令行中添加多个编辑命令

  1. $ cat << EOF > sed.txt
  2. > I love Java
  3. > I love Python
  4. > I love scale
  5. > EOF
  6. $ sed -n -e '/Java/p' -e '/Python/p' sed.txt
  7. I love Java
  8. I love Python

除了使用 -e 选项外,也可以通过将多个编辑命令使用 ; 分割的方式来达到同样的效果

  1. $ sed -e '/Java/p;/Python/p' -n sed.txt
  2. I love Java
  3. I love Python

-f

有时候 sed 的编辑命令会很复杂,直接把命令写在命令行终端会很长,不是很容易看,可以通过添加 -f 选项,读取文件文本作为编辑命令的方式来实现

  1. $ cat << EOF > command.sed
  2. > /Java/p
  3. > EOF
  4. $ echo "I love Java" | sed -n -f command.sed
  5. I love Java

-r

一般情况下 sed 只能使用标准正则表达式,如果想让 sed 支持扩展正则表达式的话,需要加上 -r 参数

  1. $ cat << EOF > sed.txt
  2. > I love Java
  3. > I love Python
  4. > I love scale
  5. > EOF
  6. $ sed -n '/Java|Python/p' sed.txt

上面示例,在执行完 sed 命令后,终端没有任何输出,这是因为 sedJava|Python 当成一个整体去匹配了,如果想达到匹配 JavaPython 字符串的效果,需要加上 -r 参数,使其支持扩展正则表达式

  1. $ cat << EOF > sed.txt
  2. > I love Java
  3. > I love Python
  4. > I love scale
  5. > EOF
  6. $ sed -n -r '/Java|Python/p' sed.txt
  7. I love Java
  8. I love Python

-i

使用 sed 对文件进行操作的时候,默认不会修改文件的内容,如果想修改文件内容的话,可以加 -i 选项

  1. $ cat << EOF > sed.txt
  2. > I love Java
  3. > I love Python
  4. > I love scale
  5. > EOF
  6. $ sed -i 's/love/like/' sed.txt
  7. $ cat sed.txt
  8. I like Java
  9. I like Python
  10. I like Scale

匹配模式

以下 sed 命令均使用下面文本进行演示

  1. $ cat << EOF > sed.txt
  2. > I love Java
  3. > I love Python
  4. > I love scale
  5. > EOF

精确匹配行

精确匹配到某一行,可以通过直接指定行号的方式进行匹配

  1. $ sed -n '2p' sed.txt
  2. I love Python

匹配从第几行~第几行

如果知道要匹配的行号是从第几行开始~第几行结束,可以直接指定两个行号,中间用 , 隔开

  1. $ sed -n '1,2p' sed.txt
  2. I love Java
  3. I love Python

匹配从第几行开始,往后多读几行

比如从第一行开始匹配,往后多读1行,即匹配1,2行

  1. $ sed -n '1,+1p' sed.txt
  2. I love Java
  3. I love Python

正则匹配

可以通过正则匹配,匹配需要处理的行。将正则表达式写在 // 中间即可

  1. $ sed -n '/Java/p' sed.txt
  2. I love Java
  3. $ sed -n '/Ja.*/p' sed.txt
  4. I love Java

匹配pattern开始~pattern结束的行

  1. $ sed -n '/Java/,/Python/p' sed.txt
  2. I love Java
  3. I love Python

区间匹配

如果是想匹配一个区间的话,上面几种匹配模式可以混搭

  1. $ sed -n '/Java/,+1p' sed.txt
  2. I love Java
  3. I love Python
  4. $ sed -n '1,/Python/p' sed.txt
  5. I love Java
  6. I 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 : 替换行内所有匹配到的字符串,忽略大小写

以下编辑命令的演示,均适用下面的数据进行演示

  1. $ cat << EOF > sed.txt
  2. > I love Java
  3. > I love Python
  4. > I love scale
  5. > EOF

p

  1. $ echo "hello" | sed -n 'p'
  2. hello

a

使用 a 编辑命令,在行后追加文本的时候,会换行

  1. $ echo "hello" | sed 'a world'
  2. hello
  3. world
  4. $ sed '/Java/a very much' sed.txt
  5. I love Java
  6. very much
  7. I love Python
  8. I love Scale

i

同样的,使用 i 编辑命令,在行前追加文本的时候,也会新建新建一行

  1. $ sed '/Java/i very much' sed.txt
  2. very much
  3. I love Java
  4. I love Python
  5. I love Scale

r

r 编辑命令其实跟 a 的作用相同,都是在行后追加文本,只不过 r 命令追加的文本内容是从外部文件读取,而 a 命令追加的文本是从命令行读取

  1. $ cat << EOF > append.txt
  2. > this is append msg
  3. > EOF
  4. $ sed '/Java/r append.txt' sed.txt
  5. I love Java
  6. this is append msg
  7. I love Python
  8. I love Scale

w

w 作用是将匹配到的行信息写入到外部文件中,写入方式是覆盖写入,不是追加

  1. $ echo "hello" | sed -n 'w test_w.txt'
  2. $ cat test_w.txt
  3. hello
  4. $ sed -n '/Java/w test_w.txt' sed.txt
  5. $ cat test_w.txt
  6. hello

d

d 删除命令,会删除匹配到的行,一般配合 -i 选项使用

  1. $ sed '/Java/d' sed.txt
  2. I love Python
  3. I love Scale
  4. $ sed '1d' sed.txt
  5. I love Python
  6. I love Scale
  7. $ sed -i '/Java/d' sed.txt
  8. $ cat sed.txt
  9. I love Python
  10. I love Scale

注意,使用 p 命令删除行的时候,一般不会加 -n 参数,加了 -n 参数往往会事与愿违

  1. $ sed -i -n '1d' sed.txt
  2. $ cat sed.txt

上面示例,加上 -n 参数后, sed.txt 文本会被清空

s/old/new/

只会替换匹配到的第一个字符串

  1. $ echo "I love Java so so so so much" | sed 's/so/aaa/'
  2. I love Java aaa so so so much

s/old/new/g

想要替换匹配到的所有字符串,可以使用 s/old/new/g

  1. $ echo "I love Java so so so so much" | sed 's/so/aaa/g'
  2. I love Java aaa aaa aaa aaa much

s/old/new/2g

从匹配到的第 n 个字符串开始替换

  1. $ echo "I love Java so so so so much" | sed 's/so/aaa/2g'
  2. I love Java so aaa aaa aaa much
  3. $ echo "I love Java so so so so much" | sed 's/so/aaa/3g'
  4. I love Java so so aaa aaa much

s/old/new/ig

  1. $ echo "I love Java so so so so much" | sed 's/So/aaa/ig'
  2. I love Java aaa aaa aaa aaa much

可以将 s/old/new/2gs/old/new/ig 这两种匹配模式合起来一起用

  1. echo "I love Java so so so so much" | sed 's/So/aaa/i2g'
  2. I love Java so aaa aaa aaa much
  3. echo "I love Java so so so so much" | sed 's/So/aaa/2ig'
  4. I love Java so aaa aaa aaa much

方向引用

& : 引用匹配模式匹配到的整个字符串
\n : 引用匹配模式匹配到的第n个字符串

&

  1. $ sed 's/love \(.*\)/& very much/' sed.txt
  2. I love Java very much
  3. I love Python very much
  4. I love scale very much

\n

使用 \n 可以引用匹配到的第几个字符串,使用 \n 的时候,要匹配的字符串必须用 () 括起来

  1. $ sed 's/love \(.*\)/\1 very much/' sed.txt
  2. I Java very much
  3. I Python very much
  4. I scale very much
  5. # 将两个文本调换位置
  6. $ sed 's/\(love\)\(.*\)/\2 \1/' sed.txt
  7. I Java love
  8. I Python love
  9. I scale love