Linux Sed 教程:学习文本编辑的语法与实例
Sed 简介
Sed 是“流编辑器”的缩写。流指的是字节的源或目标。换句话说,sed 可以从标准输入(stdin)读取输入,对流应用指定的编辑,并自动将结果输出到标准输出(stdout)。Sed 语法允许在命令行上指定输入文件。但是,该语法不直接支持输出文件规范;这可以通过输出重定向或原地编辑文件(可选择备份原始副本)来实现。Sed 是 Linux 和类 Unix 系统上最强大的工具之一。学习它是值得的,因此在本教程中,我们将从 sed 命令语法和示例开始。
教程要求
要求:Linux
Root 权限:否
难度级别:简单
类别:文本处理
操作系统兼容性:BSD • Linux • macOS • Unix
预计阅读时间:15 分钟
目录
- Sed 工作原理
- 语法
- 编辑命令
- 寻址
- 示例
- 打印
- 替换(查找和替换)
- 读取文件
- 删除行
- 插入/追加文本
- 创建 Sed 脚本
- 写入命令
- 在 Dockerfile 中使用 Sed
- 在 Shell 脚本中使用 Sed
- 总结
使用 Sed 编辑器执行非交互式编辑
Sed 是一个流编辑器。对于交互式文本编辑,您可以使用 vi/vim、nano 或 emacs 等编辑器。但是,sed 适用于在命令行界面(CLI)的脚本或 Dockerfile 中进行非交互式文件编辑。
默认情况下,sed 以非破坏性方式操作。您需要指定输出文件来保存更改,或使用特殊的 GNU sed 选项来原地编辑文件。它提供正则表达式(regex)以实现强大的文本操作。
Sed 工作原理
Sed 逐行工作。它将每一行读入模式缓冲区,通过 sed 命令修改该行,然后将缓冲区输出到标准输出(stdout),可以重定向到另一个文件。默认情况下,原始文件不会被修改。
Sed 维护两个数据缓冲区
Sed 命令维护两个数据缓冲区。两者最初都是空的:
- 模式缓冲区(活动模式空间):当 sed 从输入中逐行读取时,它将该行放入模式空间。这是进行文本操作的地方。例如,您可以使用 s 进行替换、d 进行删除、p 进行打印等 sed 命令。默认情况下,模式空间在每行读取周期结束时被清除。
- 保持缓冲区(辅助保持空间):顾名思义,保持缓冲区充当保持空间。它是 sed 用于临时存储的辅助缓冲区。可以将其视为保存数据的地方,以便在处理不同行时稍后使用。您可以使用它进行高级操作,如复制、追加、比较或检索命令。保持缓冲区的典型用法是在排序的输入文件中查找重复行或将多行连接在一起进行高级编辑。与模式空间不同,保持空间在周期之间保留其内容,除非您显式更改它。换句话说,这允许您跨多行存储和召回信息。您使用特定的 sed 命令(h、H、g、G、x)在模式空间和保持空间之间移动数据。
简而言之,模式空间是进行即时编辑的地方,而保持空间提供了一种为更复杂的编辑任务保存和召回信息的方法。标准输入(stdin)通常是键盘、文件或其他数据流。标准输出(stdout)通常是屏幕或文件。
GNU Linux Sed 命令语法
通常 GNU 版本的 sed 运行如下:
|
|
更准确的语法:
|
|
您在运行时不需要与 sed 编辑器交互;因此,它也被称为批处理编辑器。这与 Vim (vi)、emacs、nano 和 ed 等交互式编辑器形成对比。由于 sed 不需要交互,您可以将 sed 命令放在脚本中。您可以调用脚本文件并针对数据文件运行它以执行重复的编辑操作:
|
|
GNU Sed 编辑命令
最有用的 sed 命令灵感来自 vi (vim) 和 ed,99% 的用户大量使用它们:
表 1:Sed 命令
命令 | 描述 |
---|---|
d | 删除行 |
p | 打印行 |
i | 插入行 |
r | 读取文件 |
s | 替换字符串(在文件中查找和替换文本) |
w | 写入文件 |
除此之外,GNU/sed 命令还有一些有用的 CLI 选项:
表 2:GNU/sed CLI 选项
CLI 选项 | 描述 |
---|---|
-n | 抑制模式空间的自动打印(即默认输出) |
-f script | 从脚本文件读取 sed 命令 |
-i {BACKUP} | 原地编辑文件。这对于 Dockerfile 和其他此类用法非常有用 |
–posix | 禁用 sed 的所有 GNU 扩展。当您为 Unix、macOS、*BSD 和 Linux 编写 sed 脚本时,这很有用 |
-E 或 -r | 在脚本中使用扩展正则表达式 |
Sed 寻址
在我们看实际示例之前,您需要理解的最后一件事是 sed 寻址,它说明了如何指定输入文件的哪些行应受 sed 命令的影响。除非您指定地址,否则 sed 编辑器会处理所有输入文件行。此地址可以是一系列行号、正则表达式或两者的组合。如果您不提供任何地址,sed 命令将应用于输入的每一行。
地址类型:
- 行号 – 您可以指定特定的行号(例如,42)以定位该行。您可以使用
$
表示输入的最后一行,或者当在正则表达式中使用时,$
字符表示行尾(EOL)。 - 正则表达式(regex) – 您可以使用正则表达式(例如,
/pattern/
)来选择匹配特定模式的行。简而言之,只有包含模式的行会被编辑。 - 地址范围 – 您可以使用行号和/或正则表达式的组合来指定一系列行,用逗号分隔(例如,
100,200
或/word1/,/word2/
)。
示例
考虑以下 data.txt 文件,这里是标题信息:
|
|
使用 cat 命令或 bat 命令显示的随机示例数据:
|
|
使用 Sed 打印(p 命令)文本文件数据
以下示例说明如何使用 p(打印)命令,该命令将一系列行打印到 stdout。范围由起始地址后跟逗号和结束地址指定。例如,尝试打印第 5 到第 8 行:
|
|
Sed 的默认输出是它读取的每一行。要隐藏或抑制默认输出,请使用 -n
选项:
|
|
以下命令打印所有包含模式 Software
的行,即所有包含单词 ‘Software’ 的匹配行。使用正斜杠(/
)分隔正则表达式:
|
|
输出:
|
|
正则表达式后的 I
标志使其不区分大小写模式:
|
|
以下 sed 命令打印包含模式 David
的第一行,直到并包括包含模式 Emily
的下一行,即打印两个匹配单词或模式之间的行:
|
|
以下 sed 命令显示包含模式 Ashley
的第一行,直到文件的最后一行,使用 $
作为输入的最后一行:
|
|
在此示例中,将上述 sed 命令输出