Linux sed(Stream EDitor)是一个在Linux或Unix操作系统中非常强大和灵活的命令行工具,用于对文本进行处理和转换。sed命令非常强大,能够对文本进行精确和高效的处理。然而,需要注意sed是一种流编辑器,它会将处理结果输出到标准输出,而不会修改原始文件,除非使用 -i 选项。

1、命令简介

sed:流编辑器过滤和转换文本。

2、命令语法

sed [OPTION]... {script-only-if-no-other-script} [input-file]...

3、命令描述

sed是一个流编辑器。流编辑器用于对输入流(来自管道的文件或输入)执行基本的文本转换。虽然在某些方面类似于允许脚本编辑的编辑器(例如ed),但sed只对输入进行一次传递,因此效率更高。但是,sed在管道中过滤文本的能力使其与其他类型的编辑器特别不同。

4、命令选项

标签

描述

-n, --quiet, --silent

抑制自动打印模式空间

-e script, --expression=script

将脚本添加到要执行的命令中

-f script-file, --file=script-file

将脚本文件的内容添加到要执行的命令中

-i[SUFFIX], --in-place[=SUFFIX]

就地编辑文件

(如果提供扩展名,则创建备份)

-c, --copy

在-i模式下,

使用复制而不是重命名来处理文件

(避免更改输入文件的所有权)

-l N, --line-length=N

为‘l’命令指定所需的换行长度

--posix

禁用所有GNU扩展。

-r, --regexp-extended

在脚本中使用扩展的正则表达式

-s, --separate

将文件视为独立的,

而不是一个连续的长流

-u, --unbuffered

从输入文件中加载最少量的数据,

并更频繁地刷新输出缓冲区

--help

显示此帮助信息并退出

--version

输出版本信息并退出

如果没有提供 -e--expression-f--file 选项,则第一个非选项参数将被视为需要解释的 sed 脚本。

其余的所有参数将被视为输入文件的名称;如果没有指定输入文件,则读取标准输入。

1)零地址命令(zero address command)

零地址命令(zero address command)指的是那些不对输入流中的任何特定行进行操作的命令。

标签

描述

: label

b 和 t 命令的标签。

#comment

注释延伸到下一个换行符

(或-e脚本片段的结尾)。

}

{ } 块的结束括号。

2)零或一地址命令

零或一地址命令是指不依赖于特定的行号或只对单行进行操作的命令。

标签

描述

=

打印当前行号。

a \ text

追加文本,

每个嵌入的换行符前都有一个反斜杠。

i \ text

插入文本,

每个嵌入的换行符前都有一个反斜杠。

q

立即退出sed脚本,

不再处理任何输入,

但如果未禁用自动打印,

则会打印当前模式空间。

Q

立即退出sed脚本,

不再处理任何输入。

r filename

追加从文件名读取的文本。

R filename

追加从文件名读取的一行。

3)接受地址范围的命令

标签

描述

{

开始一个命令块(以}结束)。

b label

跳转到标签;如果省略标签,

则跳转到脚本末尾。

t label

如果自上次读取输入行以来,

s///命令进行了成功的替换,

则跳转到标签;如果省略标签,

则跳转到脚本末尾。

T label

如果自上次读取输入行以来,

s///命令未进行成功的替换,

则跳转到标签;如果省略标签,

则跳转到脚本末尾。

c \ text

用文本替换选定的行,

每个嵌入的换行符前都有一个反斜杠。

d

删除模式空间。开始下一周期。

D

删除模式空间中

第一个嵌入的换行符之前的内容。

开始下一周期,

但如果模式空间中仍有数据,

则跳过读取输入。

h H

复制/追加模式空间到保持空间。

g G

复制/追加保持空间到模式空间。

x

交换保持空间和模式空间的内容。

l

以“视觉上明确的”形式列出当前行。

n N

读取/追加下一行输入到模式空间。

p

打印当前模式空间。

P

打印当前模式空间中的第一个嵌入换行符

之前的内容。

s/regexp/replacement/

尝试将正则表达式匹配到模式空间。

如果成功,则用替换部分替换匹配部分。

替换部分可以包含特殊字符&,

以引用匹配的部分,

还可以包含特殊转义符\1到\9,

以引用正则表达式中的相应匹配子表达式。

w filename

将当前模式空间写入文件。

W filename

将当前模式空间的第一行写入文件。

y/source/dest/

将模式空间中出现在source中的字符

转换为dest中的相应字符。

sed 命令可以在没有地址的情况下给出,此时命令将对所有输入行执行;可以使用一个地址,此时命令只会对匹配该地址的输入行执行;也可以使用两个地址,此时命令将对匹配从第一个地址开始到第二个地址结束的包含性行范围内的所有输入行执行。关于地址范围,需要注意三点:语法是 addr1,addr2(即地址由逗号分隔);即使 addr2 选择了更早的行,addr1 匹配的行也将始终被接受;如果 addr2 是正则表达式,则不会对 addr1 匹配的行进行测试。

在地址(或地址范围)之后,并在命令之前,可以插入一个 !,指定只有在地址(或地址范围)不匹配时才执行命令。

支持以下地址类型:

标签

描述

number

仅匹配指定的行号。

first~step

从第 first 行开始,每隔 step 行匹配一次。

例如,"sed -n 1

2p" 将打印输入流中的所有奇数行,而地址 2

5 将从第二行开始每隔五行匹配一次。(这是一个扩展功能。)

$

匹配最后一行。

/regexp/

匹配与正则表达式 regexp 匹配的行。

\cregexpc

匹配与正则表达式 regexp 匹配的行。c 可以是任何字符。

GNU sed 还支持一些特殊的两地址形式:

标签

描述

0,addr2

进入“匹配第一个地址”状态,直到找到 addr2。这类似于 1,addr2,但如果 addr2 匹配输入的第一行,则 0,addr2 形式将位于其范围的末尾,而 1,addr2 形式仍将位于其范围的开头。

addr1,+N

将匹配 addr1 及其后的 N 行。

addr1,~N

将匹配 addr1 及其后的行,直到下一行的输入行号是 N 的倍数。

5、使用示例

1)基本替换

将文件 file.txt 中的所有 "foo" 替换为 "bar":

sed 's/foo/bar/g' file.txt

2)直接修改文件内容

将文件 file.txt 中的所有 "foo" 替换为 "bar",并直接保存修改:

sed -i 's/foo/bar/g' file.txt

3)删除行

删除文件 file.txt 中包含 "foo" 的所有行:

sed '/foo/d' file.txt

4)插入和追加文本

在包含 "foo" 的行之后插入 "bar":

sed '/foo/a\bar' file.txt

在包含 "foo" 的行之前插入 "bar":

sed '/foo/i\bar' file.txt

5)替换特定行的内容

将文件 file.txt 中的第3行替换为 "bar":

sed '3c\bar' file.txt

6)打印特定行

打印文件 file.txt 中的第2到第4行:

sed -n '2,4p' file.txt

7)使用正则表达式

将文件 file.txt 中所有以 "foo" 开头的行中的 "foo" 替换为 "bar":

sed '/^foo/s/foo/bar/' file.txt

8)替换第一个匹配项

只替换每行中的第一个 "foo" 为 "bar":

sed 's/foo/bar/' file.txt

9)替换带有特殊字符的文本

替换包含斜杠的路径,将 "/usr/local/bin" 替换为 "/opt/bin":

sed 's/\/usr\/local\/bin/\/opt\/bin/g' file.txt

10)多个命令

同时执行多个命令:

sed -e 's/foo/bar/g' -e 's/baz/qux/g' file.txt

11)使用脚本文件

将 sed 命令写入脚本文件 script.sed:

s/foo/bar/g
/pattern/d

运行脚本文件:

sed -f script.sed file.txt

12. 匹配行范围

删除文件 file.txt 中从包含 "start" 的行到包含 "end" 的行之间的所有行:

sed '/start/,/end/d' file.txt

13. 使用零地址命令

打印文件 file.txt 中每一行的行号:

sed '=' file.txt

推荐文档