Sed - 2:常用功能

文本替换

1
[address]s/pattern/replacement/flags

4种常用替换标记:

  • n数字 : 表明仅替换前n个被pattern匹配的内容
  • g : 表明替换所有匹配的地方。如果flags为空,则默认替换第一次匹配。
  • p : 仅当行被pattern匹配时,打印模式空间的内容
  • w file : 将替换的结果写入到文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ cat data
This is a test of the test script.
This is the second test of the test script.
$
$ sed 's/test/trail/' data #默认替换每一行的第1次匹配
This is a trail of the test script.
This is the second trail of the test script.
$
$ sed 's/test/trial/2' data #只替换每一行的第2次匹配
This is a test of the trial script.
This is the second test of the trial script.
$
$ sed 's/test/trial/g' data #替换所有的匹配
This is a trial of the trial script.
This is the second trial of the trial script.

p替换标记会打印包含与制定模式匹配的行,经常会和-n选项一起使用,实现只打印修改过的行。

1
2
3
4
5
6
7
8
9
10
11
$ cat data
This is a test line.
This is a different line.
$
$ sed -n 's/test/trial/p' data #只打印修改过的行
This is a trial line.
$
$ sed 's/test/trial/p' data #未使用-n选项,sed默认将打印所有行,造成修改过的行被打印两次。
This is a trial line.
This is a trial line.
This is a different line.

还有两种只有GNU sed中才支持的替换标记:

  • i : 忽略大小写
  • e : 把模式空间中内容作为shell命令执行,结果返回模式空间。
1
2
3
4
5
6
7
8
9
10
11
$ cat files.txt
/etc/passwd
/etc/group
$
$ sed 's/^/ls -l /' files.txt #在每行开头加上"ls -l "
ls -l /etc/passwd
ls -l /etc/group
$
$ sed 's/^/ls -l /e' files.txt #在每行开头加上"ls -l ",然后执行,输出结果。
-rw-r--r-- 1 root root 1547 Oct 27 08:11 /etc/passwd
-rw-r--r-- 1 root root 651 Oct 27 08:11 /etc/group

在replacemnt部分中经常使用的几个特殊的元字符:

  • &: 被pattern匹配的内容;
  • \num: 被pattern匹配的第num个分组
  • : 转义符号,用来转义&,, 回车等符号
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
$ cat employee.txt
101,John Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Sales Manager

#匹配开头的三位数字,在数字两边加中括号
$ sed 's/^[0-9][0-9][0-9]/[&]/g' employee.txt
[101],John Doe,CEO
[102],Jason Smith,IT Manager
[103],Raj Reddy,Sysadmin
[104],Anand Ram,Developer
[105],Jane Miller,Sales Manager

#匹配第一个都好之前的字符串,\1代表正则表达式中用()包含的第1个分组
$ sed 's/\([^,]*\).*/\1/g' employee.txt
101
102
103
104
105

# 匹配三个逗号隔开的字符串,\1 \3 代表第1和第3个分组
$ sed 's/\([^,]*\),\([^,]*\),\([^,]*\).*/\1,\3/g' employee.txt
101,CEO
102,IT Manager
103,Sysadmin
104,Developer
105,Sales Manager

行操作

添加行和插入行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ sed '[address]a\the-line-to-append' input-file # 在指定行后append一个新行
$ sed '[address]i\the-line-to-append' input-file # 在指定行前insert一个新行

$ cat lines.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.

$ sed '3i\
> This is an inserted line.' lines.txt
This is line number 1.
This is line number 2.
This is an inserted line.
This is line number 3.
This is line number 4.

$ sed '3a\
This is an inserted line.' lines.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is an inserted line.
This is line number 4.

删除行

1
2
3
4
5
6
7
8
9
10
$ sed '[address]d'

$ sed '3d' lines.txt
This is line number 1.
This is line number 2.
This is line number 4.

$ sed '2,3d' lines.txt
This is line number 1.
This is line number 4.

修改行

1
2
3
4
5
6
7
8
$ sed '[address]c\the-line-to-insert' input-file

$ sed '3c\
> This is a changed line of text' lines.txt
This is line number 1.
This is line number 2.
This is a changed line of text
This is line number 4.

打印命令

1
2
3
[address]p
[address]=
[address]l

p命令用于打印匹配行的内容

1
2
$ sed -n '/number 2/p' lines.txt
This is line number 2.

=命令用于打印匹配行的行号

1
2
3
4
5
6
7
8
9
10
11
12
$ sed '=' lines.txt
1
This is line number 1.
2
This is line number 2.
3
This is line number 3.
4
This is line number 4.

$ sed -n '/number 3/=' lines.txt
3

l命令用于打印数据流中文本和p命令不能打印的ASCII字符

1
2
3
4
5
$ cat tab.txt 
This line contains tabs.
$
$sed -n 'l' tab.txt # 'l' 命令将文本中的制表符\t和换行符$都打印出来
This\tline\tcontains\ttabs.$

转换命令

1
[address]y/inchars/outchars/

转换命令会进行inchars和outchars的一对一转换。转换命令是一个全局操作,它会自动替换文本行中找到的所有指定字符。

1
2
3
4
5
$ sed 'y/123/789/' lines.txt
This is line number 7.
This is line number 8.
This is line number 9.
This is line number 4.

更多内容……

Sed - 1: 基本概念
Sed - 3: 高级功能
Sed - 4: 经典用例

其他参考资料

SED单行脚本快速参考