提到 sed 命令,就不得提到 Sed 工具。Sed(stream editor)是一种非交互式的流编辑器,通过多种转换修改流经它的文本。
首先,Sed 通过文件或管道读取文件的内容,在默认情况下,Sed 并不会修改原文件的本身,而是将读入的内容复制到缓冲区中,也称为模式空间。所有的操作指令都是在模式空间中进行的,随后 Sed 根据相应的指令对模式空间中的内容进行处理并输出结果,默认输出到屏幕上。
Sed 工作的流程如图 1 所示。
图 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,在样本文件中写入如下内容:
hello worldh1helloh1
h2helloh2
h3helloh3
把 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
hello worldSed的高级用法
Sed 工具还提供了一些高级特性,允许处理跨多行的文本模式。
1) 加倍行间距
加倍文本内容的行间距主要在于保持空间的默认值。通常使用G命令将保持空间的内容附加到模式空间内容中,当使用 Sed 工具时,保持空间只有一个空行,将它附加到已有行的后面即可创建一个空白行。
【例 2】在样本文件 text 中插入空白行。
创建一个名为 text 的样本文件,在其中写入如图下内容:
hello在终端页面输入如下命令:
[root@bogon ~] # sed 'G' text
hello可以看出,在文件的末尾处也产生了一个空白行,如果不想要这个空白行,可以使用排出符号“!”和尾行符号“$”来确保空白行不加在最后一行,如下所示:
hello2) 使用等号“=”显示数据流中行的行号
【例 3】显示数据流中行的行号。
使用例 2 中 text 样本文件的内容,在终端页面输入如下命令:
[root@bogon ~] # sed '=' text
1
2
hello3
4
还可以将行号和文本放在同一行。在使用等号命令输出之后,通过管道将输出传给另一个 sed 脚本,再使用 N 命令来合并这两行,最后使用替换命令将换行符更换成空格或制表符。
在终端页面输入如下命令:
[root@bogon ~]# sed '=' text | sed 'N; s/\n/ /'
1
2
hello3
hello world4
注意,Next(N)指令通过读取新的输入行,并将它追加至模式空间的现有内容之后,来创建多行模式空间。模式空间的最初内容与新的输入行之间用换行符分隔,在模式空间中插入的换行符可以使用“\n”匹配。
3) 多行删除操作(D)
d 指令为删除指令,其作用是删除模式空间中的内容并读入新的输入行,如果 sed 在 d 指令后还有多条指令,则余下的指令将不再执行,而是返回第一条指令对新读入行进行处理。
而多行删除指令 D 将删除模式空间中直到第一个插入的换行符(\n)前的内容,它不会读入新的输入行,并返回 sed 脚本的顶端,使得剩余指令继续应用于模式空间中剩余的内容。
【例 4】显示数据流中行的行号。
创建一个名为 text 的样本文件,在样本文件中写入如下内容:
hellohttp://www.weixueyuan.net
123456
abcdef
在终端页面输入如下命令:
[root@bogon ~]# nl text | sed '1d;5d'
1
2
hello3
hello world4
5 http://www.weixueyuan.net
6 123456
7 abcdef
【例 5】删除 HTML 标签。标准的 HTML Web 页面包含一些不同类型的 HTML 标签。HTML 标签由小于号和大于号来识别。大部分 HTML 标签都是成对出现的:一个起始标签和一个结束标签。
创建一个样本文件命名为 text,在样本文件中写入如下内容:
hellohello world
12345
在终端页面输入如下命令:
[root@bogon ~]# sed 's/]*//g' text
hello
hello world
123456
可以看出,HTML 标签已经被删除,但还有多余的空白行。因此可以加入删除命令来删除多余的空白行。命令如下:
[root@bogon ~]# sed 's/]*>//g; /^$/d' text
hello
hello world
123456