Linux Sed 文本编辑教程:语法与实例详解

本教程详细介绍了Linux Sed流编辑器的核心概念、语法结构和实用示例。内容涵盖文本替换、删除、插入、正则表达式匹配等操作,并展示了在Dockerfile和Shell脚本中的实际应用场景,帮助读者掌握非交互式文本处理技巧。

Linux Sed 教程:学习文本编辑的语法与实例

Sed 简介

Sed 是“流编辑器”的缩写。流指的是字节的源或目标。换句话说,sed 可以从标准输入(stdin)读取输入,对流应用指定的编辑,并自动将结果输出到标准输出(stdout)。Sed 语法允许在命令行上指定输入文件。但是,该语法不直接支持输出文件规范;这可以通过输出重定向或原地编辑文件(可选择备份原始副本)来实现。Sed 是 Linux 和类 Unix 系统上最强大的工具之一。学习它是值得的,因此在本教程中,我们将从 sed 命令语法和示例开始。

教程要求

要求:Linux
Root 权限:否
难度级别:简单
类别:文本处理
操作系统兼容性:BSD • Linux • macOS • Unix
预计阅读时间:15 分钟

目录

  1. Sed 工作原理
  2. 语法
  3. 编辑命令
  4. 寻址
  5. 示例
  6. 打印
  7. 替换(查找和替换)
  8. 读取文件
  9. 删除行
  10. 插入/追加文本
  11. 创建 Sed 脚本
  12. 写入命令
  13. 在 Dockerfile 中使用 Sed
  14. 在 Shell 脚本中使用 Sed
  15. 总结

使用 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 运行如下:

1
2
3
sed 'commands' input_file 
sed 'commands' input_file > output_file
sed 'commands' input_file | command2

更准确的语法:

1
2
sed [options][addresses] action [args]’ input_files [ > outfile]
sed [options][addresses] action [args]’ input_files [ | command_2]

您在运行时不需要与 sed 编辑器交互;因此,它也被称为批处理编辑器。这与 Vim (vi)、emacs、nano 和 ed 等交互式编辑器形成对比。由于 sed 不需要交互,您可以将 sed 命令放在脚本中。您可以调用脚本文件并针对数据文件运行它以执行重复的编辑操作:

1
sed SCRIPT input_file

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 文件,这里是标题信息:

1
NAME|DOB|Location|Job Title|Salary $

使用 cat 命令或 bat 命令显示的随机示例数据:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
John Doe|1985-03-15|New York|Software Engineer|80000
Aarav Patel|1990-06-21|Mumbai|Data Analyst|88000
Jane Smith|1992-11-20|London|Data Scientist|95000
David Lee|1978-07-08|Tokyo|Project Manager|110000
Thandiwe Zulu|1993-04-03|Cape Town|Business Analyst|93000
Li Wei|2002-07-25|Shanghai|AI Researcher|86000
Priya Sharma|1987-01-14|Delhi|Software Tester|79000
Sipho Nkosi|1976-11-29|Johannesburg|IT Manager|102000
Sarah Jones|2001-05-02|Paris|Web Developer|75000
Michael Brown|1969-12-25|Sydney|System Administrator|90000
Emily Davis|1998-09-10|Berlin|UX Designer|85000
Kevin Wilson|1975-04-30|Toronto|Database Admin|100000
Jessica Garcia|2003-01-18|Rome|QA Tester|70000
Kenji Kimura|1973-02-07|Kyoto|Systems Engineer|99000
Brian Rodriguez|1982-08-22|Madrid|Network Engineer|92000
Ashley Williams|1995-06-05|Amsterdam|Frontend Developer|78000
Christopher Martinez|1972-10-12|Vienna|Security Analyst|98000
Amanda Anderson|2000-02-28|Dublin|Mobile Developer|82000
Matthew Thomas|1988-09-01|Stockholm|Cloud Architect|105000
Elizabeth Jackson|1979-11-17|Helsinki|DevOps Engineer|97000
Daniel White|2004-03-09|Copenhagen|Junior Developer|68000
Zhang Lei|1984-05-11|Beijing|Cybersecurity Expert|94000

使用 Sed 打印(p 命令)文本文件数据

以下示例说明如何使用 p(打印)命令,该命令将一系列行打印到 stdout。范围由起始地址后跟逗号和结束地址指定。例如,尝试打印第 5 到第 8 行:

1
$ sed '5,8p' data.txt

Sed 的默认输出是它读取的每一行。要隐藏或抑制默认输出,请使用 -n 选项:

1
$ sed -n '5,8p' data.txt

以下命令打印所有包含模式 Software 的行,即所有包含单词 ‘Software’ 的匹配行。使用正斜杠(/)分隔正则表达式:

1
$ sed -n '/Software/p' data.txt

输出:

1
2
John Doe|1985-03-15|New York|Software Engineer|80000
Priya Sharma|1987-01-14|Delhi|Software Tester|79000

正则表达式后的 I 标志使其不区分大小写模式:

1
$ sed -n '/software/Ip' data.txt

以下 sed 命令打印包含模式 David 的第一行,直到并包括包含模式 Emily 的下一行,即打印两个匹配单词或模式之间的行:

1
$ sed -n '/David/,/Emily/p' data.txt

以下 sed 命令显示包含模式 Ashley 的第一行,直到文件的最后一行,使用 $ 作为输入的最后一行:

1
$ sed -n '/Ashley/,$p' data.txt

在此示例中,将上述 sed 命令输出

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计