首页 > 编程笔记

Linux sed命令用法详解

提到 sed 命令,就不得提到 Sed 工具。Sed(stream editor)是一种非交互式的流编辑器,通过多种转换修改流经它的文本。

首先,Sed 通过文件或管道读取文件的内容,在默认情况下,Sed 并不会修改原文件的本身,而是将读入的内容复制到缓冲区中,也称为模式空间。所有的操作指令都是在模式空间中进行的,随后 Sed 根据相应的指令对模式空间中的内容进行处理并输出结果,默认输出到屏幕上。

Sed 工作的流程如图 1 所示。

Sed工作流程图
图 1 Sed工作流程图

Sed 处理文本时是以行为单位的,每处理完一行就立即打印出来,然后再处理下一行,直至全文处理结束。Sed 可做的编辑动作包括删除、查找替换、添加、插入、从其他文件中读入数据等。

注意,要想保存修改后的文件,必须使用重定向生成新的文件。如果想直接修改源文件本身则需要使用“-i”参数。

sed 命令通常在以下场景中使用:
sed 的基本语法格式如下:

[root@bogon ~]# sed [选项] {脚本指令} [输入文件]

sed 常用的选项及各自的功能如表 2所示。

表 2 sed常用选项及功能
选 项 功 能
-n 使用安静(silent)模式。在一般 sed 的用法中,所有来自 STDIN 的数据一般都会被列出到终端上。 但如果加上 -n 参数后,则只有经过 sed 特殊处理的那一行或动作才会被列出来
-e 直接在命令行模式上进行 sed 的动作编辑
-f 直接将 sed 的动作写在一个文件内,-f filename 则可以运行 filename 内的 sed 动作
-r sed 的动作支持的是扩展型正规表示法的语法。(默认的是基础正规表示法语法)
-i 直接修改读取的文件内容,而不是输出到屏幕

sed 通过特定的脚本指令对文件进行处理,常用脚本指令及功能如表3  所示。

表 3 sed常用脚本指令及功能
脚本指令 功 能
a 增加,a 的后面可以接字符串,而这些字符串会在新的一行出现(当前的下一行)
c 替换,c 之后的字符串将会替换规定行之间的所有行
d 删除,删除指定的行
i 插入,在指定行的前面进行插入
l 打印,显示非打印字符
L 打印,不显示非打印字符
p 打印,将某个选择的数据打印出来。通常跟参数 -n —起运行
q 退出
r 读入文件内容
s 替换,用一个字符串替换另一个,注意与 c 的区别
w 保存至文件
y 按字符转换

【例 1】sed脚本指令:添加。
首先创建一个样本文件命名为 text,在样本文件中写入如下内容:

<html>
<title>hello world</title>
<body>
h1helloh1
h2helloh2
h3helloh3
</body>
</html>

把 text 样本文件的内容通过 sed 脚本进行添加,即把 text 文件中的第一个 h1,h2 和 h3 添加上“<>”;第一个 h1,h2 和 h3 添加上“</>”。

使用 touch 命令创建一个脚本文件,命名为 sed.sh。打开脚本文件 sed.sh,写入如下内容:

/h[0-9]/{
s//\<&\>/1
s//\<\/&\>/2
}

在终端页面输入如下命令:

[root@bogon ~]# sed –f sed.sh text
<html>
<title>hello world</title>
<body>
<h1>hello</h1>
<h2>hello</h2>
<h3>hello</h3>
</body>
</html>

Sed的高级用法

Sed 工具还提供了一些高级特性,允许处理跨多行的文本模式。

1) 加倍行间距

加倍文本内容的行间距主要在于保持空间的默认值。通常使用G命令将保持空间的内容附加到模式空间内容中,当使用 Sed 工具时,保持空间只有一个空行,将它附加到已有行的后面即可创建一个空白行。

【例 2】在样本文件 text 中插入空白行。
创建一个名为 text 的样本文件,在其中写入如图下内容:

<html>
<title>hello</title>
<body>hello world<body>
</html>

在终端页面输入如下命令:

[root@bogon ~] # sed 'G' text
<html>

<title>hello</title>

<body>hello world</body>

</html>
 

可以看出,在文件的末尾处也产生了一个空白行,如果不想要这个空白行,可以使用排出符号“!”和尾行符号“$”来确保空白行不加在最后一行,如下所示:

<html>

<title>hello</title>

<body>hello world</body>

</html>

2) 使用等号“=”显示数据流中行的行号

【例 3】显示数据流中行的行号。
使用例 2 中 text 样本文件的内容,在终端页面输入如下命令:

[root@bogon ~] # sed '=' text
1
<html>
2
<title>hello</title>
3
<body>hello world</body>
4
</html>

还可以将行号和文本放在同一行。在使用等号命令输出之后,通过管道将输出传给另一个 sed 脚本,再使用 N 命令来合并这两行,最后使用替换命令将换行符更换成空格或制表符。

在终端页面输入如下命令:

 [root@bogon ~]# sed '=' text | sed 'N; s/\n/ /'
1  <html>
2  <title>hello</title>
3  <body>hello world</body>
4  </html>

注意,Next(N)指令通过读取新的输入行,并将它追加至模式空间的现有内容之后,来创建多行模式空间。模式空间的最初内容与新的输入行之间用换行符分隔,在模式空间中插入的换行符可以使用“\n”匹配。

3) 多行删除操作(D)

d 指令为删除指令,其作用是删除模式空间中的内容并读入新的输入行,如果 sed 在 d 指令后还有多条指令,则余下的指令将不再执行,而是返回第一条指令对新读入行进行处理。

而多行删除指令 D 将删除模式空间中直到第一个插入的换行符(\n)前的内容,它不会读入新的输入行,并返回 sed 脚本的顶端,使得剩余指令继续应用于模式空间中剩余的内容。

【例 4】显示数据流中行的行号。
创建一个名为 text 的样本文件,在样本文件中写入如下内容:

<html>
<title>hello</title>
<body>hello world<body>
</html>
http://www.weixueyuan.net

123456
abcdef

在终端页面输入如下命令:

[root@bogon ~]# nl text | sed '1d;5d'
1  <html>
2  <title>hello</title>
3  <body>hello world<body>
4  </html>
5  http://www.weixueyuan.net

6  123456
7  abcdef


【例 5】删除 HTML 标签。标准的 HTML Web 页面包含一些不同类型的 HTML 标签。HTML 标签由小于号和大于号来识别。大部分 HTML 标签都是成对出现的:一个起始标签和一个结束标签。

创建一个样本文件命名为 text,在样本文件中写入如下内容:

<html>
<head>
<title>hello</title>
</head>
<body>
hello world
12345
<body>
</html>

在终端页面输入如下命令:

[root@bogon ~]# sed 's/<[^>]*//g' text
 
 
hello
 
 
hello world
123456
 
 

可以看出,HTML 标签已经被删除,但还有多余的空白行。因此可以加入删除命令来删除多余的空白行。命令如下:

[root@bogon ~]# sed 's/<[^>]*>//g; /^$/d' text
hello
hello world
123456

优秀文章