余苏明的幻想乡

Chapter 1: Sed Syntax and Basic Commands

Chapter 1: Sed Syntax and Basic Commands

sed examples

使用的sed 案例均为下面文件

1
2
3
4
5
6
$ vi 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. Sed Command Syntax

sed基本语法

1
sed [options] {sed-commands} {input-file}

sed读取文本为按行读取匹配

输出/etc/passwd文件的所有行

1
2
3
4
5
6
7
8
9
10
11
sed -n 'p' /etc/passwd
[root@localhost ~]# sed -n 'p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt

sed命令文件的基本语法

1
sed [options] -f {sed-commands-in-a-file} {input-file}

sed命令文件格式为一行一个sed命令,实现多个sed命令

1
2
3
4
5
6
[root@localhost SedAwk]# cat test-script.sed
/^root/ p
/^nobody/ p
[root@localhost SedAwk]# sed -n -f test-script.sed /etc/passwd
root:x:0:0:root:/root:/bin/bash
nobody:x:99:99:Nobody:/:/sbin/nologin

sed使用-e参数实现多个sed命令

1
sed [options] -e {sed-command-1} -e {sed-command-2} {input-file}
1
2
3
[root@localhost SedAwk]# sed -n -e '/^root/ p' -e '/^nobody/ p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
nobody:x:99:99:Nobody:/:/sbin/nologin

为了方便阅读,可以使用\换行

1
2
3
4
sed -n \
-e '/^root/ p' \
-e '/^nobody/ p' \
/etc/passwd

也可以使用{}包括命令组

1
2
3
4
sed [options] '{
sed-command-1
sed-command-2
}' input-file

例如:

1
2
3
4
5
6
[root@localhost SedAwk]# sed -n '{
> /^root/ p
> /^nobody/ p
> }' /etc/passwd
root:x:0:0:root:/root:/bin/bash
nobody:x:99:99:Nobody:/:/sbin/nologin


2.Sed Scripting Flow

Sed命令运行步骤

  • Read 逐行读取
  • Execute 逐行执行命令 one by one
  • Print 可以是空匹配
  • Repeat 重复步骤执行步骤

3. Print Pattern Space (p command)

Using the sed p command, you can print the current pattern space.
使用p命令,你可以输出当前的模式

The following example prints every line of employee.txt twice:

单独使用p命令会使每行都输出两次

1
2
3
4
5
6
7
8
9
10
11
12
$ sed 'p' employee.txt
101,John Doe,CEO
101,John Doe,CEO
102,Jason Smith,IT Manager
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
13Sed and Awk 101 Hacks
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
104,Anand Ram,Developer
105,Jane Miller,Sales Manager
105,Jane Miller,Sales Manager

配合n命令可以只输出一次

  • -n 取消默认的输出
    1
    2
    3
    4
    5
    6
    $ sed -n 'p' employee.txt
    101,John Doe,CEO
    102,Jason Smith,IT Manager
    103,Raj Reddy,Sysadmin
    104,Anand Ram,Developer
    105,Jane Miller,Sales Manager

Specifying an Address Range 指定地址范围

如果你不指定范围,sed默认匹配全部行

1
2
$ sed -n '2 p' employee.txt
102,Jason Smith,IT Manager
1
2
3
4
5
6
$ sed -n '1,4 p' employee.txt
101,John Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
14Sed and Awk 101 Hacks

输出第二行一直到最后一行
$匹配最后一行

1
2
3
4
5
$ sed -n '2,$ p' employee.txt
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Sales Manager

Modify Address Range

三种模式:逗号模式,加号模式,和波浪号模式

  • 逗号模式
    • 表示绝对的地址范围
  • 加号模式
    • 表示相对的地址范围
  • 波浪号模式
    • 表示等差序列的步长
      1
      2
      3
      4
      1~2 matches 1,3,5,7, etc.
      2~2 matches 2,4,6,8, etc.
      1~3 matches 1,4,7,10, etc.
      2~3 matches 2,5,8,11, etc.
1
2
3
4
$ sed -n '1~2 p' employee.txt
101,John Doe,CEO
103,Raj Reddy,Sysadmin
105,Jane Miller,Sales Manager

Pattern Matching 模板匹配

1
2
$ sed -n '/Jane/ p' employee.txt
105,Jane Miller,Sales Manager

输出从第一个Jason行开始到第四行的所有行(并且输出所有的匹配到Jason的行)

1
2
3
4
$ sed -n '/Jason/,4 p' employee.txt
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer

Note: If there were no matches for “Jason” in the 1st 4 lines, this
command would print the lines that match “Jason” after the 4th line.

如果在前四行没有匹配到Jason,则在第四行之后只输出匹配到Jason的行

1
2
3
4
$ sed -n '/Raj/,$ p' employee.txt
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Sales Manager
1
2
3
4
$ sed -n '/Raj/,/Jane/ p' employee.txt
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Sales Manager

如果Raj匹配行后没有找到Jane匹配行,则输出到最后行。(不管前面是否有Jane行,都不会输出Jane行)
该模式会循环匹配(Jane之后还有RajJane也会输出,只有Raj会输出后面所有行)

1
2
3
4
5
6
7
8
9
10
11
12
13
st=>start: start
op=>operation: read a line
op1=>operation: print
op2=>operation: skip
op3=>operation: read a line
op4=>operation: print
cond=>condition: Raj yes or no?
cond1=>condition: Jane yes or no?
ed=>end
st->op->cond(yes)->op1->op3->cond1(no)->op1
cond(no)->op2->op
cond1(yes)->op4->op

1
2
3
4
$ sed -n '/Jason/,+2 p' employee.txt
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer

4. Delete Lines (d command)

使用d参数,可以删除行。

NOTE:d参数仅仅只删除输出流,就像其他的sed参数,并不会修改原始文件。
如果不使用其他参数,单独使用d参数,则匹配所有行,所以不会有任何输出。

相当于p参数的非,不显示匹配到的行。如果前面使用-n参数,则不会有任何输出
因为d参数没有输出功能,-n参数是取消默认输入的输出

1
sed 'd' employee.txt

Useful Delete Examples (常用实例)

删除空行:

1
sed '/^$/ d' employee.txt

删除所有注释行:

1
sed '/^#/ d' employee.txt

NOTE:当使用多个命令参数匹配同一行时,d命令执行之后会删除匹配行,不会在删除行进一步执行后续命令

1
2
3
4
5
[root@localhost SedAwk]# sed -n -e '2 d' -e '2 p' employee.txt
[root@localhost SedAwk]# sed -n -e '2 p' -e '2 d' employee.txt
102,Jason Smith,IT Manager
[root@localhost SedAwk]#

5. Write Pattern Space to File (w command)

将标准输出输入到指定文件

Write the content of employee.txt file to file output.txt (and display on screen):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ sed 'w output.txt' employee.txt
101,John Doe,CEO
102,Jason Smith,IT Manager
19Sed and Awk 101 Hacks
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Sales Manager
$ cat output.txt
101,John Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Sales Manager

Write the content of employee.txt file to output.txt file but not to screen:

-n参数,将不会输出标准输入

使用w参数会覆盖原本文件里面的内容

1
2
3
4
5
6
7
8
$ sed -n 'w output.txt' employee.txt
$ cat output.txt
101,John Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Sales Manager

Write only the 2nd line:

1
2
3
4
$ sed -n '2 w output.txt' employee.txt
$ cat output.txt
102,Jason Smith,IT Manager

Note: You might not use the w command frequently. Most people use
UNIX output redirection, instead, to store the output of sed to a file.
For example: sed 'p' employee.txt > output.txt
你可能不会使用w命令,因为大部分在UNIX系统中,使用>符号代替