C.1. Sed

Sed 是一个非交互式的[1] 编辑器。 它接收文本输入,无论是来自stdin还是来自文件,对输入的指定行执行特定操作,一次一行,然后将结果输出到stdout或文件。 在 shell 脚本中,sed 通常是管道中几个工具组件之一。

Sed 根据传递给它的地址范围确定要操作输入中的哪些行。[2] 可以通过行号或要匹配的模式指定此地址范围。 例如,3d表示 sed 删除输入的第 3 行,并且/Windows/d告诉 sed 您希望删除输入中包含与 "Windows" 匹配的每一行。

sed 工具包的所有操作中,我们将主要关注三个最常用的操作。 它们是打印(到stdoutstdout),删除替换

表 C-1. 基本的 sed 操作符

操作符名称效果
[地址范围]/p打印打印 [指定的地址范围]
[地址范围]/d删除删除 [指定的地址范围]
s/pattern1/pattern2/替换将 pattern2 替换为行中 pattern1 的第一个实例
[地址范围]/s/pattern1/pattern2/替换在地址范围内,将 pattern2 替换为行中 pattern1 的第一个实例
[地址范围]/y/pattern1/pattern2/转换在地址范围内,将 pattern2 替换为行中 pattern1 的第一个实例内,将 pattern1 中的任何字符替换为 pattern2 中的相应字符(等同于 tr
[地址] i pattern Filename插入在文件 Filename 中指示的地址处插入 pattern。 通常与-i 原地选项一起使用。
g全局对输入中每个匹配行的每个模式匹配进行操作

Note

除非将g全局)操作符附加到 substitute 命令,否则替换仅对每行中模式匹配的第一个实例进行操作。

从命令行和 shell 脚本中,sed 操作可能需要引用和某些选项。

sed -e '/^$/d' $filename
# The -e option causes the next string to be interpreted as an editing instruction.
#  (If passing only a single instruction to sed, the "-e" is optional.)
#  The "strong" quotes ('') protect the RE characters in the instruction
#+ from reinterpretation as special characters by the body of the script.
# (This reserves RE expansion of the instruction for sed.)
#
# Operates on the text contained in file $filename.

在某些情况下,sed 编辑命令将无法与单引号一起使用。

filename=file1.txt
pattern=BEGIN

  sed "/^$pattern/d" "$filename"  # Works as specified.
# sed '/^$pattern/d' "$filename"    has unexpected results.
#        In this instance, with strong quoting (' ... '),
#+      "$pattern" will not expand to "BEGIN".

Note

Sed 使用-e选项来指定以下字符串是指令或一组指令。 如果字符串中仅包含单个指令,则可以省略此选项。

sed -n '/xzy/p' $filename
# The -n option tells sed to print only those lines matching the pattern.
# Otherwise all input lines would print.
# The -e option not necessary here since there is only a single editing instruction.

表 C-2. sed 操作符示例

表示法效果
8d删除输入的第 8 行。
/^$/d删除所有空白行。
1,/^$/d从输入开头删除到第一个空白行(包括第一个空白行)。
/Jones/p仅打印包含 "Jones" 的行(使用 -n 选项)。
s/Windows/Linux/"Linux" 替换为每行输入中找到的 "Windows" 的第一个实例。
s/BSOD/stability/g"stability" 替换为每行输入中找到的 "BSOD" 的每个实例。
s/ *$//删除每行末尾的所有空格。
s/00*/0/g将所有连续的零序列压缩为单个零。
echo "Working on it." | sed -e '1i How far are you along?'打印 “How far are you along?” 作为第一行,“Working on it” 作为第二行。
5i 'Linux is great.' file.txt在 file.txt 文件的第 5 行插入 ‘Linux is great.’。
/GUI/d删除所有包含 "GUI" 的行。
s/GUI//g删除 "GUI" 的所有实例,保留每行其余部分不变。

将零长度字符串替换为另一个字符串等同于删除输入行中的该字符串。 这将保留该行其余部分不变。 应用s/GUI//到行

The most important parts of any application are its GUI and sound effects
结果为
The most important parts of any application are its  and sound effects

反斜杠强制 sed 替换命令继续到下一行。 这具有使用第一行末尾的换行符作为替换字符串的效果。

s/^  */\
/g
此替换将行首空格替换为换行符。 最终结果是将段落缩进替换为段落之间的空白行。

地址范围后跟一个或多个操作可能需要使用花括号括起来,并带有适当的换行符。

/[0-9A-Za-z]/,/^$/{
/^$/d
}
这仅删除每组连续空白行的第一个。 这可能对单倍行距文本文件很有用,但会保留段落之间的空白行。

Note

sed 使用的常用分隔符是 /。 但是,sed 允许其他分隔符,例如 %。 当 / 是替换字符串的一部分时,例如在文件路径名中,这很有用。 请参阅 示例 11-10示例 16-32

Tip

快速将文本文件加倍行距的方法是sed G filename.

有关 shell 脚本中 sed 的示例,请参阅

  1. 示例 36-1

  2. 示例 36-2

  3. 示例 16-3

  4. 示例 A-2

  5. 示例 16-17

  6. 示例 16-27

  7. 示例 A-12

  8. 示例 A-16

  9. 示例 A-17

  10. 示例 16-32

  11. 示例 11-10

  12. 示例 16-48

  13. 示例 A-1

  14. 示例 16-14

  15. 示例 16-12

  16. 示例 A-10

  17. 示例 19-12

  18. 示例 16-19

  19. 示例 A-29

  20. 示例 A-31

  21. 示例 A-24

  22. 示例 A-43

  23. 示例 A-55

有关 sed 的更深入处理,请参阅 参考书目 中的相关参考资料。

注释

[1]

Sed 在没有用户干预的情况下执行。

[2]

如果未指定地址范围,则默认值为所有行。