基本 sed 使用

调用 sed 有两种方式:在命令行上或者执行文件。

下面是一个简单的例子:

1
2
3
4
5
6
7
8
9
$ cat cat.txt
line3
asdad 4tert
asdgg line

$ sed 's/l/L/g' cat.txt
Line3
asdad 4tert
asdgg Line

有三种方式可以指定命令行上的多重指令:

  • 分号分割
  • 在每个指令前使用 -e
  • 使用 bash 分行指令

下面是对上面的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ sed 's/l/L/g;s/i/I/g' cat.txt
LIne3
asdad 4tert
asdgg LIne

$ sed -e 's/l/L/g' -e 's/i/I/g' cat.txt
LIne3
asdad 4tert
asdgg LIne

$ sed '
quote> s/l/l/g
quote> s/i/I/g' cat.txt
lIne3
asdad 4tert
asdgg lIne

sed 的默认操作是输出每个输入行。-n 选项可以阻止自动输出。如果要输出指令需要包含打印命令 p。如下例子:

1
2
3
$ sed -n -e 's/l/L/gp' cat.txt
Line3
asdgg Line

在脚本中使用命令

看下面 sed 的命令文件:

1
2
3
4
5
6
7
$ cat sed.txt
s/l/L/g
s/L/P/g
$ cat cat.txt
line3
asdad 4tert
asdgg line

如果对 cat.txt 文件进行处理的话会出现如下的结果:

1
2
3
4
$ sed -f sed.txt cat.txt
Pine3
asdad 4tert
asdgg Pine

从上面的例子可以看出来,在 sed 执行的时候会把第一行用命令文件当中的第一行来处理,然后将返回值当做下一行命令的输入,最后返回最终的结果。

我们也可以指定包含某些字符的行进行处理:

1
2
3
4
$ sed '/asd/ s/line/LINE/g' cat.txt
line3
asdad 4tert
asdgg LINE

上面的例子是表示包含 asd 的行当中把 line 替换成 LINE。

其中上面的 /asd/ 我们可以叫做匹配地址,sed 命令可以指定 0-2 个地址,会有如下的规则。

  • 如果没匹配地址,那么命令会应用于每一行。
  • 如果只有一个地址,那么命令应用于与这个地址匹配的任意行。
  • 如果指定了由逗号分割的两个地址,那么命令应用于匹配第一个地址的第一行和它后面的行,一直到匹配第二个地址的行(包括此行)。
  • 如果地址后面带 ! ,那么命令就应该用于不匹配该地址的所有行。

如下例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ cat cat.txt
line3
asdad 4tert
asdgg line
sd2 line
pwddf line
fsd line

$ sed '/asd/,/pwd/ s/line/LINE/g' cat.txt
line3
asdad 4tert
asdgg LINE
sd2 LINE
pwddf LINE
fsd line

使用下面的例子来解释寻址:

1
2
3
4
5
6
/^$/d #删除空行
/^\.TS/,/^\.TE/d #删除由 .TS 开头到 .TE 开头中间的所有行
1d #删除第一行
$d #删除最后一行
50,$d #删除 50 到最后一行
1,/^$/d #删除第一行到第一个空行的所有行

分组命令

sed 中使用大括号 {} 将一个地址嵌套在另外一个地址中,或者在相同地址上使用多个命令,看如下例子:

1
2
3
4
5
6
7
8
9
10
11
12
$ cat ca
.a asdad 4tert

asd line
.b sdd line
sd s line

$ sed '/^\.a/,/^\.b/{/^$/d;s/line/Line/}' ca
.a asdad 4tert
asd Line
.b sdd Line
sd s line

首先找到 .a 开头到 .b 开头的行,在这些行当中删除空行和把 line 替换成 Line。

【参考资料】

  1. sed与awk

—EOF—