> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/man/man1/sed.1.md).

# sed.1

`sed` — 流编辑器

## 名称

`sed`

## 概要

`sed [-Ealnru] command [-I extension] [-i extension] [file]`

`sed [-Ealnru] [-e command] [-f command_file] [-I extension] [-i extension] [file]`

## 描述

`sed` 实用程序读取指定文件，如果未指定文件则读取标准输入，按照命令列表的指定修改输入。然后将输入写入标准输出。

可将单个命令指定为 `sed` 的第一个参数。可使用 `-e` 或 `-f` 选项指定多个命令。所有命令都按指定顺序应用于输入，无论其来源如何。

可用选项如下：

**`-E`** 将正则表达式解释为扩展（现代）正则表达式，而非基本正则表达式（BRE）。re\_format(7) 手册页完整描述了两种格式。

**`-a`** 默认情况下，列为“w”函数参数的文件在任何处理开始前创建（或截断）。`-a` 选项使 `sed` 延迟打开每个文件，直到包含相关“w”函数的命令应用到某行输入。

**`-e`** `command` 将 `command` 参数指定的编辑命令追加到命令列表。

**`-f`** `command_file` 将文件 `command_file` 中找到的编辑命令追加到命令列表。每个编辑命令应单独列在一行。如果 `command_file` 为“`-`”，则从标准输入读取命令。

**`-I`** `extension` 就地编辑文件，并以指定 `extension` 保存备份。如果给定零长度 `extension`，则不保存备份。不建议在就地编辑文件时给定零长度 `extension`，因为在磁盘空间耗尽等情况下可能导致文件损坏或内容不完整。注意，使用 `-I` 就地编辑仍在覆盖所有文件的单个连续行地址空间中进行，尽管每个文件保持其个体性而非形成一个输出流。行计数器在文件之间从不重置，地址范围可跨越文件边界，“$”地址仅匹配最后一个文件的最后一行。（参见 [sed 地址](#sed-地址)。）这在许多就地编辑情况下可能导致意外结果，此时应使用 `-i`。

**`-i`** `extension` 类似于 `-I` 就地编辑文件，但将每个文件独立于其他文件处理。具体而言，每个文件中的行号从 1 开始，“$”地址匹配当前文件的最后一行，地址范围限于当前文件。（参见 [sed 地址](#sed-地址)。）最终效果如同每个文件由单独的 `sed` 实例编辑。

**`-l`** 使输出行缓冲。

**`-n`** 默认情况下，每行输入在应用所有命令后回显到标准输出。`-n` 选项抑制此行为。

**`-r`** 同 `-E`，用于与 GNU sed 兼容。

**`-u`** 使输出无缓冲。

`sed` 命令的形式如下：

```sh
[address[,address]]function[arguments]
```

可在第一个地址和命令的函数部分之前插入空白。

通常，`sed` 循环地将一行输入（不包括其终止换行符）复制到 *pattern space*（除非“D”函数后留下了内容），应用所有地址选中该模式空间的命令，将模式空间复制到标准输出并追加换行，然后删除模式空间。

部分函数使用 *hold space* 保存全部或部分模式空间以供后续检索。

## sed 地址

地址不是必需的，但如果指定，必须为以下格式之一：

* 累计计算输入文件输入行号的数字（如果 `-i` 选项生效，则为每个文件独立计算）；
* 美元符号（“$”）字符，寻址输入的最后一行（如果指定了 `-i` 选项，则为当前文件的最后一行）；
* 上下文地址，由前后各带一个分隔符的正则表达式组成。结尾分隔符后还可选择性地跟“**I**”字符，表示正则表达式以不区分大小写的方式匹配。

无地址的命令行选择每个模式空间。

具有一个地址的命令行选择所有匹配该地址的模式空间。

具有两个地址的命令行选择一个闭区间。此范围从匹配第一个地址的第一个模式空间开始。范围的结尾是匹配第二个地址的下一个模式空间。如果第二个地址是小于或等于首次选中行号的数字，则仅选择该行。第二个地址中的数字可以加（“+”）前缀，以指定第一个模式之后要匹配的行数。当第二个地址是上下文地址时，`sed` 不会将第二个地址重新与匹配第一个地址的模式空间进行匹配。从选中范围之后的第一行开始，`sed` 重新开始查找第一个地址。

通过使用感叹号（“!”）函数，可将编辑命令应用于未选中的模式空间。

## sed 正则表达式

`sed` 中使用的正则表达式默认为基本正则表达式（BRE，更多信息参见 re\_format(7)），但如果给定 `-E` 标志，则可使用扩展（现代）正则表达式。此外，`sed` 在正则表达式上有以下两处扩展：

* 在上下文地址中，除反斜杠（“\*\*\*\*”）或换行符外的任何字符都可用于分隔正则表达式。起始分隔符前需加反斜杠，除非它是斜杠。例如，上下文地址 **`\exabcx`** 等同于 `/abc/`。此外，在正则表达式中，在分隔字符前加反斜杠字符会使该字符被字面处理。例如，在上下文地址 **`\exabc\exdefx`** 中，RE 分隔符是“x”，第二个“x”代表其自身，因此正则表达式为“abcxdef”。
* 转义序列 **`\n`** 匹配嵌入模式空间的换行符。但是，不能在地址或替换命令中使用字面换行符。

`sed` 正则表达式的一个特殊功能是它们可以默认为上次使用的正则表达式。如果正则表达式为空，即仅指定了分隔字符，则改用上次遇到的正则表达式。上次正则表达式定义为作为地址或替换命令一部分使用的最后一个正则表达式，且在运行时而非编译时确定。例如，命令“/abc/s//XXX/”会将“XXX”替换为模式“abc”。

## sed 函数

在以下命令列表中，每个命令允许的最大地址数以 \[0addr]、\[1addr] 或 \[2addr] 表示，分别代表零个、一个或两个地址。

参数 *text* 由一行或多行组成。要在文本中嵌入换行符，在其前加反斜杠。文本中的其他反斜杠被删除，后跟的字符按字面处理。

“r”和“w”函数接受可选的文件参数，该参数应通过空白与函数字母分隔。作为 `sed` 参数给出的每个文件在任何输入处理开始前创建（或其内容被截断）。

“b”、“r”、“s”、“t”、“w”、“y”、“!”和“:”函数都接受附加参数。以下概要指示哪些参数必须通过空白字符与函数字母分隔。

两个函数接受 function-list。这是由换行符分隔的 `sed` 函数列表，如下所示：

```sh
{ function
  function
  ...
  function
}
```

“{”前可加空白，后可加空白。函数前可加空白。终止的“}”前必须加换行符，也可加空白。

**\[2addr] function-list** 仅在选中模式空间时执行 function-list。

\**\[1addr]a\** **text** 在每次尝试读取一行输入之前（无论是通过执行“N”函数还是通过开始新循环），立即将 *text* 写入标准输出。

**\[2addr]b\[label]** 跳转到具有指定标签的“:”函数。如果未指定标签，跳转到脚本末尾。

\**\[2addr]c\** **text** 删除模式空间并开始下一循环。对于 0 或 1 个地址，或在 2 地址范围的末尾，*text* 被写入标准输出。

**\[2addr]d** 删除模式空间并开始下一循环。

**\[2addr]D** 删除模式空间中从开头到第一个换行符的初始段，并开始下一循环。

**\[2addr]g** 用保持空间的内容替换模式空间的内容。

**\[2addr]G** 在模式空间后追加换行符和保持空间的内容。

**\[2addr]h** 用模式空间的内容替换保持空间的内容。

**\[2addr]H** 在保持空间后追加换行符和模式空间的内容。

\**\[1addr]i\** **text** 将 *text* 写入标准输出。

**\[2addr]l** （字母 ell。）以视觉上无歧义的形式将模式空间写入标准输出。此形式如下：不可打印字符以三位八进制数（带前导反斜杠）按字符中每个字节写入（最高有效字节在前）。长行被折叠，折叠点以反斜杠后跟换行符表示。每行末尾以“$”标记。其中转义序列表示如下：

**backslash** **`\\`** **alert** **`\a`** **form-feed** **`\f`** **carriage-return** **`\r`** **tab** **`\t`** **vertical tab** **`\v`**

**\[2addr]n** 如果未抑制默认输出，将模式空间写入标准输出，并用下一行输入替换模式空间。

**\[2addr]N** 将下一行输入追加到模式空间，使用嵌入的换行符将追加内容与原始内容分隔。注意当前行号会改变。

**\[2addr]p** 将模式空间写入标准输出。

**\[2addr]P** 将模式空间中从开头到第一个换行符的部分写入标准输出。

**\[1addr]q** 跳转到脚本末尾并退出，不开始新循环。

**\[1addr]r** file 在下次尝试读取一行输入之前，立即将 *file* 的内容复制到标准输出。如果 *file* 因任何原因无法读取，将被静默忽略且不设置错误条件。

**\[2addr]s/regular expression/replacement/flags** 用替换字符串替换模式空间中正则表达式的第一个实例。除反斜杠或换行符外的任何字符都可代替斜杠用于分隔 RE 和替换字符串。在 RE 和替换字符串中，如果 RE 分隔符本身前加反斜杠，则可作为字面字符使用。替换字符串中出现的与号（“&”）被匹配 RE 的字符串替换。“&”在此上下文中的特殊含义可通过在其前加反斜杠来抑制。字符串“**#**”，其中“#”是数字，被相应反向引用表达式匹配的文本替换（参见 re\_format(7)）。可通过在行中替换换行符来分割行。要在替换字符串中指定换行符，在其前加反斜杠。替换函数中 *flags* 的值为以下零个或多个：

**`N`** 仅对模式空间中正则表达式的第 `N` 次出现进行替换。

**`g`** 对正则表达式的所有非重叠匹配进行替换，而非仅第一个。

**`p`** 如果进行了替换，将模式空间写入标准输出。如果替换字符串与其所替换的字符串相同，仍视为已进行替换。

**`w`** *file* 如果进行了替换，将模式空间追加到 *file*。如果替换字符串与其所替换的字符串相同，仍视为已进行替换。

**`i`** 或 **`I`** 以不区分大小写的方式匹配正则表达式。

**\[2addr]t** \[label] 如果自最近一次读取输入行或执行“t”函数以来进行了任何替换，跳转到带标签的“:”函数。如果未指定标签，跳转到脚本末尾。

**\[2addr]w** *file* 将模式空间追加到 *file*。

**\[2addr]x** 交换模式空间和保持空间的内容。

**\[2addr]y/string1/string2/** 将模式空间中 *string1* 中所有出现的字符替换为 *string2* 中相应字符。除反斜杠或换行符外的任何字符都可代替斜杠用于分隔字符串。在 *string1* 和 *string2* 中，反斜杠后跟除换行符外的任何字符为该字面字符，反斜杠后跟 “n” 被换行符替换。

**\[2addr]!function** **\[2addr]!function-list** 仅将函数或 function-list 应用于未被地址选中的行。

**\[0addr]:label** 此函数不执行任何操作；它承载一个标签，“b”和“t”命令可跳转到此标签。

**\[1addr]=** 将行号写入标准输出，后跟换行符。

**\[0addr]** 空行被忽略。

**\[0addr]#** “#”和该行其余部分被忽略（视为注释），唯一例外是如果文件前两个字符为“#n”，则抑制默认输出。这与在命令行上指定 `-n` 选项相同。

## 环境变量

`COLUMNS`、`LANG`、`LC_ALL`、`LC_CTYPE` 和 `LC_COLLATE` 环境变量影响 `sed` 的执行，如 [environ(7)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man7/environ.7.md) 中所述。

## 退出状态

`sed` 实用程序成功时退出值为 0，发生错误时大于 0。

## 实例

从另一命令管道替换 `bar` 为 `baz`：

```sh
echo "use bar in examples" | sed 's/bar/baz/'
```

使用反斜杠有时难以阅读和跟踪：

```sh
echo "/bin/bash" | sed 's/\/bin\/bash/\/bin\/sh/'
```

处理路径时使用不同的分隔符可能更方便：

```sh
echo "/bin/bash" | sed 's#/bin/bash#/bin/sh#'
```

在文件 `test.txt` 中将所有出现的 `foo` 替换为 `bar`，不创建文件备份：

```sh
sed -i '' -e 's/foo/bar/g' test.txt
```

## 参见

[awk(1)](/man/man1/awk.1.md), ed(1), [grep(1)](/man/man1/grep.1.md), regex(3), re\_format(7)

> Lee E. McMahon, "SED — A Non-interactive Text Editor", 77, AT\&T Bell Laboratories, January 1979.

## 标准

`sed` 实用程序预期为 IEEE Std 1003.2（"POSIX.2"）规范的超集。

`-E`、`-I`、`-a` 和 `-i` 选项，`-f` `-` 的特殊含义，地址范围第二个成员中的“+”前缀，以及地址正则表达式和替换命令的“**I**”标志是非标准 FreeBSD 扩展，可能无法在其他操作系统上使用。

## 历史

由 L. E. McMahon 编写的 `sed` 命令出现在 Version 7 AT\&T UNIX 中。

## 作者

Diomidis D. Spinellis <dds@FreeBSD.org>

## 缺陷

包含值为 0x5C（ASCII “\*\*\*\*”）字节的多字节字符可能在“a”、“c”和“i”命令的参数中被错误地视为行延续字符。多字节字符不能用作“s”和“y”命令的分隔符。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://book.bsdcn.org/man/man1/sed.1.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
