文章

SED 使用技巧

编写服务器脚本经常需要用 SED,整理常用 SED 操作技巧收藏一下,以备不时之需。

简单的匹配删除

删除匹配的行(/d):

1
2
3
4
5
6
7
8
cat <<EOF | sed '/^\s*key1:/d'
section1:
  key1: value1
  key2: value2
section2:
  key1: value1
  key2: value2
EOF

删除不匹配的行(/d换成/!d):

1
2
3
4
5
6
7
8
cat <<EOF | sed '/^\s*key1:/!d'
section1:
  key1: value1
  key2: value2
section2:
  key1: value1
  key2: value2
EOF

简单的匹配替换

直接替换匹配的行:

1
2
3
4
5
6
7
8
cat <<EOF | sed '/#key3:/c\  key3: value3'
section1:
  key1: value1
  key2: value2
  #key3: value3
section2:
  key4=value4
EOF

替换匹配的行时引用匹配值:

1
2
3
4
5
6
7
8
cat <<EOF | sed 's/^\(\s*\)#\(.*\)$/\1\2/g'
section1:
  key1: value1
  key2: value2
  #key3: value3
section2:
  key4=value4
EOF

简单的增加内容

插入内容到匹配的行之前:

1
2
3
4
5
6
7
8
cat <<EOF | sed '/section1:/i\common:'
section1:
  key1: value1
  key2: value2
  #key3: value3
section2:
  key4=value4
EOF

添加内容到匹配的行之后:

1
2
3
4
5
6
7
8
9
cat <<EOF | sed '/common:/a\  key: value'
common:
section1:
  key1: value1
  key2: value2
  #key3: value3
section2:
  key4=value4
EOF

复杂的模式匹配操作

先看看通用的例子:

1
2
3
4
5
6
sed '/pattern1/,/pattern2/ {
  ...
  /pattern3/,/pattern4/ {
    ...
  }
} file

通过一些简单操作的无限组合,可完成非常复杂的操作。一些特殊的匹配规则如下:

  • /pattern/:模式匹配pattern内容,其中1$表示匹配首行和尾行;
  • /pattern/!:模式不匹配pattern内容;
  • /pattern1/,/pattern2/{...}:模式匹配pattern1pattern2之间内容,{...}操作只在匹配内容之间有效,可以无限套娃;

删除首行到第 N 行内容:

1
2
3
4
5
6
7
8
cat <<EOF | sed '1,+2d'
section1:
  key1: value1
  key2: value2
section2:
  key1: value1
  key2: value2
EOF

删除匹配行到尾行内容:

1
2
3
4
5
6
7
8
cat <<EOF | sed '/section2:/,$d'
section1:
  key1: value1
  key2: value2
  #key3: value3
section2:
  key4=value4
EOF

也可以这样:

1
2
3
4
5
6
7
8
9
10
cat <<EOF | sed '/section2:/,$ {
  /.*/d
}'
section1:
  key1: value1
  key2: value2
  #key3: value3
section2:
  key4=value4
EOF

/.*/d可以简写为d

删除两个模式匹配行之间的内容:

1
2
3
4
5
6
7
8
9
10
11
12
cat <<EOF | sed '/section1:/,/section2:/{
  /section1:/!{
    /section2:/!d
  }
}'
section1:
  key1: value1
  key2: value2
  #key3: value3
section2:
  key4=value4
EOF

替换两个模式匹配行之间的内容:

1
2
3
4
5
6
7
8
9
10
cat <<EOF | sed '/section1:/,/section2:/ {
  s#key1#key3#g
}'
section1:
  key1: value1
  key2: value2
section2:
  key1: value1
  key2: value2
EOF

也可以这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
cat <<EOF | sed '/section1:/ {
  :a
  n
  s#key1#key3#g
  /section2:/!ba
}'
section1:
  key1: value1
  key2: value2
section2:
  key1: value1
  key2: value2
EOF
  • :a表示定义一个名为a的跳转标签,ba则为跳转到a标签;
  • n表示读取下一行。

删除匹配的行下一行到尾行内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
cat <<EOF | sed '/section2:/ {
  p
  :a
  N
  $!ba
  d
}'
section1:
  key1: value1
  key2: value2
section2:
  key1: value1
  key2: value2
EOF
  • p表示打印匹配行,也就是section2:
  • N表示追加下一行到模式匹配。

参考

https://wangchujiang.com/linux-command/c/sed.html

本文由作者按照 CC BY 4.0 进行授权