zzxworld

Linux sed 命令使用指南

Linux sed 命令使用指南

sed 命令给我的感觉是 Linux 中最复杂的命令之一,难度堪比编程语言中的正则表达式。不过复杂背后带来的是强大的功能。在掌握了它的用法后,相当于是得到了一件在 Linux 系统上处理文本的利器。

sed 命令格式

sed [选项]... {脚本} [输入文件]...

如果没有给出 -e--expression-f,或者 --file 选项,第一个非选项参数会被当作 sed 命令的脚本来解释。所有余下的参数是输入文件的名称。如果没有指定输入文件,默认会从标准输入读取内容。

sed 命令示例

光看上面的命令格式可能还不明就里,直接来看例子。假设要把 test.txt 文件中的 abc 小写字母替换为 ABC 大写字母:

sed 's/abc/ABC/' test.txt

上面的命令会输出执行替换后的内容,但还没有真正去修改文件内容,可以当作是命令处理脚本的预览。如果要直接修改文件内容,需要使用 -i 选项:

sed -i 's/abc/ABC/' test.txt

再去看看文件内容,符合条件的文字一定被修改了。命令脚本中的 / 是定界符,除了这个符号,: 也可以拿来做定界符:

sed 's:abc:ABC:' test.txt

除了替换字符,sed 命令还可以用来清理文件中的空白行:

sed '/^$/d' test.txt

删除指定行,比如要删除第 3 行:

sed '2d' test.txt

按行区间来删除,比如从 3 行到最后一行都删除:

sed '2,$d' test.txt

删除以 abc 开头的行:

sed '/^abc/d' test.txt

匹配 abc 并给匹配到的内容加上中括号:

sed 's/abc/[&]/' test.txt

sed 命令选项

缩写 完整名称 说明
-n --quiet, --silent 不自动打印模式空间的内容。
-e 脚本 --expression=脚本 添加脚本到将要执行的命令。
-f 脚本文件 --file=脚本文件 添加脚本文件的内容到即将执行的命令。
--follow-symlinks 处理已存在文件时跟随链接。
-i[SUFFIX] --in-place[=SUFFIX] 编辑已存在的文件(如果提供了SUFFIX作为后缀则做备份)。
-l N --line-length=N 指定 l 命令需要的自动换行长度。
--posix 禁用所有GNU插件。
-E -r --regexp-extended 在脚本中使用扩展正则表达式(为了可移植性,请使用符合POSIX的-E)。
-s --separate 将多个文件分别看待,而非统一视作同个连续的流。
--sandbox 在沙箱模式下操作。
-u --unbuffered 从输入文件中读取最少量的数据并更频繁地刷新输出缓冲区。
-z --null-data 用 NUL 字符分割行。
--help 显示这个帮助并退出。
--version 输出版本信息并退出。

sed 命令提供的选项不多,核心在于脚本命令。sed 主要的脚本命令如下:

名称 说明
: label bt 命令的标签。
#comment 注释将会延长到下一个新行(或者一个 -e 脚本片段的结尾)。
} 一个 { } 块的闭括号。
= 答应当前行的行号。
a \ text 追加 text, text 可以通过预先写入反斜杠来嵌入新行。
i \ text 插入 text, text 可以通过预先写入反斜杠来嵌入新行。
q [exit-code] 立即退出 sed 脚本而不处理其他输入,除非自动打印没有禁用使得当前模式空间将会被打印。[exit-code] 是 GNU 插件。
Q [exit-code] 立即退出 sed 脚本而不处理其他输入。这是一个GNU插件。
r 文件名 从文件名读取内容并追加到最后。
R 文件名 从文件名读取一行并追加到最后。每次调用这个命令就从文件中读取一行。
{ 开始一个命令块,以 } 符号结束。
b label 程序跳转到 label 处;如果 label 被省略,跳转到脚本尾部。
c \ text text 代替选择的行, text 可以通过预先写入反斜杠来嵌入新行。
d 删除模式空间。
D 如果模式空间包含新行,在 d 命令发布之后开始一个新的普通循环。否则删除模式空间中的 text 直到新行,并且在不读入新行的情况下,用结果的模式空间开始一个循环。
h H 复制 / 追加模式空间到保存空间。
g G 复制 / 追加保存空间到模式空间。
l 用直观明确的格式列出当前行。
l width 用直观明确的格式列出当前行,在 width 字符处结束。这是一个 GNU 插件。
n N 读取 / 追加下一行输入到模式空间。
p 输出当前的模式空间。
P 输出直到遇到当前模式空间的第一个嵌入的换行符。
s/regexp/replacement/ 尝试与模式空间匹配 regexp,如果成功,用 replacement 代替匹配的部分 。replacement 可能包含特殊字符 & 来引用模式空间中匹配的部分,而特殊字符 \1\9 则引用 regexp 中对应匹配的子表达式。
t label 自上次输入行读取之后并且上次执行了 t 或者 T 命令之后,如果一个 s/// 被成功替换,那么跳转到 label 处;如果 label 被忽略,跳转到脚本结尾。
T label 自上此输入行读取之后并借上次执行了 t 或者 T 命令之后,如果一个 s/// 被成功替换,那么跳转到 label 处;如果 label 被忽略,跳转到脚本结尾。这是一个 GNU 插件。
w filename 将当前的模式空间写入到 filename 中。
W filename 写入当前模式空间的第一行到 filename 中。这是一个 GNU 插件。
x 交换模式空间和保存空间的内容。
y/source/dest/ 将模式空间中显示为 source 的字符用 dest 字符来写出。