Linux Sed 命令详解

sedstream editor 的简称, 是一个流编辑器。它逐行处理输入文本, 处理时, 把当前处理的行存储在临时缓冲区中, 称为 "pattern space", 接着用 sed 命令处理缓冲区中的内容, 处理完成后, 把结果输出到标准输出。接着处理下一行, 这样不断重复, 直到文件末尾。

基本语法

#   命令选项  sed 操作命令  要处理的文件
sed [option] 'command' input_file

常用选项

-n   使用安静 silent 模式。在一般 sed 的用法中, 所有来自 stdin 的内容一般都会被列出到屏幕上。但如果加上 -n 参数后, 则只有经过 sed 特殊处理的那一行 (或者动作) 才会被列出来
-e   多点编辑, 可以执行多个子命令
-f   从文件中读取 sed 命令, -f filename 则可以执行 filename 内的 sed 命令
-r   让 sed 命令支持扩展的正则表达式 (默认是基础正则表达式)
-i   直接修改文件内容, 不仅仅是输出
-l   指定每行的最大长度

常用命令

实验用文件内容 test.txt

letitia
mail
uuencode
1003605091
01566

a 命令 - 新增

在指定行后追加文本 (多行字符串可以用 \n 分隔), 而这些字串会在新的一行出现

从第一行到最后一行所有行后追加 "add one" 字符串

sed '1,$a\add one' test.txt

letitia
add one
mail
add one
uuencode
add one
1003605091
add one
01566
add one

在匹配到 mail 行后追加 "add one" 字符串

sed '/mail/a\add one' test.txt

letitia
mail
add one
uuencode
1003605091
01566

i 命令 - 插入

在匹配的行前面插入字符串行, 这些字串会在新的一行出现

在第二行之前插入一行内容 "inserted text"

sed '2i\inserted text' test.txt

letitia
inserted text
mail
uuencode
1003605091
01566

c 命令 - 替换整行

用于替换整行内容

将第二行替换为 This is a new line

sed '2cThis is a new line' test.txt

letitia
This is a new line
uuencode
1003605091
01566

从第一行到最后一行所有行替换为 "add one" 字符串

sed '1,$c\add one' test.txt

add one

将匹配到 mail 行替换为 "add one" 字符串

sed '/mail/c\add one' test.txt

letitia
add one
uuencode
1003605091
01566

s 命令 - 替换文本

用于在行内替换指定的文本内容

基本格式

sed '位置参数 s/要查找的文本/替换后的文本/[flag]'

将所有的 apple 替换为 orange

echo "I have an apple" | sed 's/apple/orange/'

I have an orange

将所有的 letitia 替换为 new

sed 's/letitia/new/g' test.txt

new
mail
uuencode
1003605091
01566

{} 要转义, 因为此处使用的不是扩展正则表达式

sed 's/[0-9]\{10\}/miss letitia/g' test.txt

letitia
mail
uuencode
miss letitia
01566

将前两行里的 l 替换为 L

sed '1,/^ma/ s/l/L/g' test.txt

Letitia
maiL
uuencode
1003605091
01566

这个例子比较复杂。使用大括号, 表示对 1 到 3 行做了一组操作

sed -n '1,3{
            s/l/L/g
            s/e/E/g
            2 i tyrone
            p
            }' test.txt

LEtitia
tyrone
maiL
uuEncodE

d 命令 - 删除

删除指定行

删除第三行

sed '3d' test.txt

letitia
mail
1003605091
01566

从第四行到最后一行全部删除

sed '4,$d' test.txt

letitia
mail
uuencode

p 命令 - 打印

打印指定行

打印第一至第三行

sed '1,3 p' test.txt

letitia
letitia
mail
mail
uuencode
uuencode
1003605091
01566

打印第一至第三行有 -n 参数

sed -n '1,3p' test.txt

letitia
mail
uuencode

观察输出结果, 不使用 -n 选项时, sed 命令把 1 到 3 行输出了两次。这是因为不使用 -n 时, sed 首先读取一行, 并默认将缓冲区内的文本输出出来, 之后 p 子命令再次输出。使用 -n 时, 默认输出取消, 只有 p 子命令的输出结果


sed 命令支持正则表达式定位。语法为 /re/, re 表示正则表达式

打印出从匹配正则表达式的地方到第 5 行, 也就是从匹配以 ma 开头的文本行处开始

sed -n '/^ma/,5 p' test.txt

mail
uuencode
1003605091
01566

first 开头 end 结尾的所有行全部打印

sed -n '/^first.*end$/p' test.txt

1~2 表示从第一行开始, 行号递增 2 输出, 即输出奇数行。语法格式为 first~step

sed -n '1~2 p' test.txt

letitia
uuencode
01566

标志选项

g             # 全局匹配, 会替换文本行中所有匹配的字符串
digit         # 替换文本行中第 n 个 (digit 是 1 至 9) 匹配的字符串
p             # 若发生了替换操作, 并且将缓冲区输出到标准输出
w file-name   # 若发生了替换操作, 并且将改动的行输出到磁盘文件中
i             # 表示进行 Regexp 匹配时, 不区分大小写字母

GNU 版本的扩展标识

\digit   # Replacement 中可含有后向引用中的 \digit (digit 是 1 至 9), 引用前面定义的子表达
&        # 代表模版空间中的整个匹配部分
\L       # 将在其后的替换部分转换成小写字母, 直到发现一个 \U 或 \E, GNU 扩展功能
\l       # 将下一个字符转换成小写字母, GNU 扩展功能
\U       # 将在其后的替换部分转换成大写字母, 直到发现一个 \L 或 \E, GNU 扩展功能
\u       # 将下一个字符转换成大写字母, GNU 扩展功能
\E       # 停止由 \L 或 \U 指示开始的大小写转换, GNU 扩展功能

基本正则表达式

元字符 说明
* * 前面的正则表达式匹配的结果重复任意次 (含 0 次)
\+ 与星号 (*) 相同, 只是至少重复 1 次, GNU 的扩展功能
\? 与星号 (*) 相同, 只是最多重复 1 次, GNU 的扩展功能
\{i\} 与星号 (*) 相同, 只是重复指定的 i
\{i,j\} 与星号 (*) 相同, 只是重复 ij
\{i, \} 与星号 (*) 相同, 只是至少重复 i
\(regexp\) regexp 看作一个整体, 用于后向引用, 与 \digit 配合使用
. 匹配任意单个字符
^ 匹配模版空间开始处的 NULL 字符串
$ 匹配的是模版空间结束处的 NULL 字符串
[list] 匹配方括号中的字符列表中的任意一个
[^list] 否定匹配方括号中的字符列表中的任意一个
regexp1|regexp2 用在相邻的正则表达式之间, 表示匹配这些正则表达式中任一个都可以。匹配是从左向右开始的, 一旦匹配成功就停止匹配
regexp1regexp2 匹配 regexp1regexp2 的连接结果
\digit 匹配正则表达式前半部分定义的后向引用的第 digit 个子表达式。digit19 的数字, 1 为从左开始
\n 匹配换行符
\meta 将元字符 meta 转换成普通字符, 以便匹配该字符本身, 有$*.[\^

扩展正则表达式

它们之间的差别很小, 那就是转义字符的使用

简称 全称 解释
BRE basic regular expressions 基础正则表达式 (过时的)
ERE extended regular expressions 扩展正则表达式 (现代的)

如果从字面理解, 基础这个字眼让 BRE 显得具有一定地位, 但实质上 BRE 的存在只是为了兼容一些老旧的软件。

基本正则表达式 扩展正则表达式
\? ?
\+ +
\| |
\{ \} { }
\( \) ( )

常用转义字符

转义字符 说明
\a 匹配一个 BEL 字符
\f 匹配一个换页字符
\n 匹配一个换行字符
\r 匹配一个回车字符
\t 匹配一个水平 Tab 字符
\v 匹配一个垂直 Tab 字符
\cX 匹配 Control+X, X 是任意字符
\dXXX 匹配一个 ASCII 码是十进制 XXX 的字符
\oXXX 匹配一个 ASCII 码是八进制 XXX 的字符
\xXX 匹配一个 ASCII 码是十六进制 XX 的字符
\w 匹配任意一个单词字符 (字母、数字和下划线)
\W 匹配任意一个非单词字符
\b 匹配一个单词的边界符: 字符的左边是一个单词字符, 并且右边是一个非单词字符, 反之亦然
\B 匹配除单词边界符外所有字符: 字符的左边和右边同时是单词字符或非单词字符

原文

Linux Sed命令详解
sed命令详解

最后更新于 2019-04-10
使用 Hugo 构建
主题 StackJimmy 设计