Linux下Shell编程之sed命令详解及示例
sed
(stream editor)是一种流编辑器,它能够对文本进行过滤和转换。sed
的工作原理是按照指定的模式对输入的文本行进行匹配,然后对匹配到的行执行相应的编辑命令。sed
非常适合于在管道中处理文本数据,并且可以用于自动化脚本中的文本处理任务。
一、基本用法
sed [选项] '脚本' 文件名
脚本
:是一个或多个sed
编辑命令的集合,用单引号括起来。文件名
:是要处理的文本文件。如果省略文件名,sed
将从标准输入读取数据。
常用选项
-e 脚本
:直接在命令行中指定sed
脚本。-f 脚本文件
:从指定的文件中读取sed
脚本。-i[SUFFIX]
:直接修改文件内容,而不是输出到标准输出。如果指定了SUFFIX
,则备份原文件,并在其后添加该后缀。-n
:取消默认输出,只输出sed
脚本处理过的行。
编辑命令
a\ 文本
:在匹配行之后插入新文本。i\ 文本
:在匹配行之前插入新文本。c\ 文本
:用新文本替换匹配行。d
:删除匹配行。p
:打印匹配行。s/原模式/新模式/[修饰符]
:用新模式替换原模式。修饰符可以是g
(全局替换),p
(打印替换结果),i
(忽略大小写)等。
模式空间与保持空间
- 模式空间:
sed
处理文本时,会将一行文本读入模式空间,然后对其执行脚本中的命令。处理完一行后,sed
会将模式空间的内容输出(除非使用了-n
选项),然后读取下一行。 - 保持空间:是
sed
的另一个缓冲区,可以用于在脚本的不同部分之间传递数据。保持空间通常用于复杂的文本处理任务。
示例
示例 1:替换文本
将文件 example.txt
中所有的 "foo" 替换为 "bar":
sed 's/foo/bar/g' example.txt
示例 2:删除行
删除文件 example.txt
中所有包含 "baz" 的行:
sed '/baz/d' example.txt
示例 3:插入文本
在文件 example.txt
中所有包含 "qux" 的行之前插入一行 "Inserted line":
sed '/qux/i\Inserted line' example.txt
示例 4:打印特定行
打印文件 example.txt
中的第 2 到第 4 行:
sed -n '2,4p' example.txt
示例 5:使用保持空间交换两行
假设你有一个文件 swap.txt
,内容如下:
Line 1
Line 2
Line 3
你想要交换第 1 行和第 3 行的位置。可以使用以下 sed
脚本:
sed -e '1{h;d}' -e '3{G;s/\(.*\)\n\(.*\)/\2\n\1/}' swap.txt
解释:
1{h;d}
:当处理第 1 行时,将其保存到保持空间(h
),然后删除模式空间的内容(d
),不输出。3{G;s/\(.*\)\n\(.*\)/\2\n\1/}
:当处理第 3 行时,将保持空间的内容追加到模式空间(G
),然后使用s
命令交换两行。
输出将是:
Line 3
Line 2
Line 1
二、高级用法及技巧
使用地址范围
sed
允许你指定地址范围,以便对特定范围内的行执行编辑命令。地址范围可以是行号、正则表达式或两者的组合。
- 行号范围:例如,
2,4
表示第 2 到第 4 行。 - 正则表达式范围:例如,
/start/,/end/
表示从匹配start
的行到匹配end
的行(包括这两行)。
示例:
# 删除第 2 到第 4 行
sed '2,4d' example.txt
# 从匹配 "start" 的行到匹配 "end" 的行,将 "foo" 替换为 "bar"
sed '/start/,/end/s/foo/bar/g' example.txt
多命令组合
你可以使用 -e
选项或分号 ;
来组合多个 sed
命令。
示例:
# 使用 -e 选项组合命令
sed -e 's/foo/bar/g' -e '2,4d' example.txt
# 使用分号组合命令
sed 's/foo/bar/g; 2,4d' example.txt
模式空间与保持空间的高级应用
模式空间和保持空间是 sed
的两个重要缓冲区。通过巧妙地使用它们,你可以执行复杂的文本处理任务。
- 模式空间:用于存储当前处理的行。
- 保持空间:用于在脚本的不同部分之间传递数据。
示例:
# 反转文件中的行顺序
sed '1!G;h;$!d' example.txt
解释:
1!G
:对于非第一行,将保持空间的内容追加到模式空间。h
:将模式空间的内容复制到保持空间。$!d
:对于非最后一行,删除模式空间的内容(不输出)。
分支与循环
sed
提供了分支(b
和 t
命令)和循环(:
和 ;
组合)的功能,可以用于构建复杂的文本处理逻辑。
- 分支:
b
命令用于无条件跳转,t
命令用于在成功执行替换后跳转。 - 循环:使用
:
标记一个标签,然后使用;
和b
命令实现循环。
示例:
# 打印文件中的奇数行
sed -n 'n;p' example.txt
解释:
n
:读取下一行到模式空间,覆盖当前行。p
:打印模式空间的内容。
由于 n
命令会覆盖当前行,因此这个脚本会跳过偶数行并打印奇数行。
使用 sed 进行文本分析和转换
sed
非常适合于文本分析和转换任务。通过结合使用正则表达式、地址范围和编辑命令,你可以轻松地提取、修改和生成文本数据。
示例:
# 提取文件中的所有电子邮件地址
sed -n 's/.*<\([^>]*\)>.*/\1/p' example.txt
解释:
s/.*<\([^>]*\)>.*/\1/
:使用正则表达式匹配电子邮件地址,并将其提取出来。p
:打印匹配的结果。
这个示例假设电子邮件地址被尖括号包围,例如 <email@example.com>
。