# sed 命令使用详细总结


# sed 命令使用详细总结

sed（Stream Editor）是Linux/Unix生态下的**非交互式流编辑器**，是文本处理三剑客（grep/sed/awk）核心成员，以逐行流式处理为核心，无需打开文件即可完成批量文本修改、过滤、提取等操作，是自动化脚本、运维文本处理的核心工具。

## 一、核心执行原理（必懂）

sed的处理逻辑全程围绕两个核心缓冲区展开，理解这一点就能彻底搞懂sed的工作模式：

- **模式空间（Pattern Space）**：主处理缓冲区，逐行读取文本后载入此处，所有编辑命令默认仅作用于此，处理完一轮即清空

- **保持空间（Hold Space）**：辅助暂存缓冲区，编辑命令无法直接作用，仅用于和模式空间交互数据，用于多行处理等高级场景

核心执行流程：

1. 读取一行文本，去除换行符后载入模式空间

2. 按「地址定位规则」匹配当前行，匹配成功则执行对应的编辑命令

3. 命令执行完成后，默认将模式空间内容（恢复换行符）输出到标准输出

4. 清空模式空间，读取下一行，循环直至文件结束

关键提示：sed**默认不修改原文件**，仅输出处理结果到终端，只有加`-i`选项才会直接修改原文件（高危操作）。

## 二、基础语法与命令格式

```Bash

# 核心语法
sed [选项] '地址定位+编辑命令' 输入文件/标准输入

# 常用扩展格式
sed [选项] -e '指令1' -e '指令2' 目标文件  # 多命令串行执行
sed [选项] -f 脚本文件 目标文件             # 从脚本文件读取sed命令
sed [选项] '地址{命令1;命令2;...}' 文件     # 同地址多命令组合执行
```

## 三、高频核心选项

|选项|全称|核心作用|高频使用场景|注意事项|
|---|---|---|---|---|
|`-n`|`--quiet/--silent`|取消默认输出，仅打印指令主动处理的结果|精准提取指定行、仅输出替换成功的行|必须和`p`打印命令配合使用，否则无输出|
|`-i[SUFFIX]`|`--in-place`|直接修改原文件，可选备份|批量修改配置文件、文本内容|高危操作！`-i.bak`会先备份原文件为`file.bak`；macOS(BSD sed)必须指定备份后缀，无备份需写`-i ''`|
|`-e`|`--expression`|指定多个编辑指令，多命令串联|同时执行替换、删除、插入等多个操作|单条命令可省略，多条命令必须每个指令前加`-e`|
|`-E/-r`|`--regexp-extended`|启用扩展正则表达式(ERE)|复杂正则匹配、分组、或逻辑`|`|
|`-f`|`--file`|从指定脚本文件读取sed命令|复杂逻辑、多命令批量执行|脚本文件中每行写一条sed命令，无需加单引号|
|`-z`|`--null-data`|按NULL字符(\0)分割行，而非换行符|处理含换行符的单行文本、JSON内容|GNU sed特有扩展|
## 四、地址定位（sed的灵魂）

sed的所有编辑命令，都可通过地址定位指定作用的行，不指定则默认作用于**所有行**。地址定位分为6大类，覆盖全场景。

### 1. 单地址定位

```Bash

sed '5d' file.txt          # 作用于第5行，删除第5行
sed '$p' file.txt          # 作用于最后一行($代表最后一行)，仅打印最后一行
sed '/error/p' file.txt    # 作用于匹配正则error的所有行，打印匹配行
sed '/^#/d' file.txt       # 作用于以#开头的行，删除注释行
```

### 2. 连续范围地址定位

```Bash

sed '2,5d' file.txt        # 作用于第2到第5行（闭区间，包含首尾）
sed '3,+4d' file.txt       # 作用于第3行及后面4行（3-7行）
sed '/start/,/end/d' file.txt  # 作用于匹配start的行 到 匹配end的行 之间的所有行
sed '5,/pattern/p' file.txt    # 作用于第5行 到 匹配pattern的行 之间的所有行
```

### 3. 步进地址定位（GNU sed特有）

语法：`起始行~步长`

```Bash

sed '1~2d' file.txt        # 奇数行删除（1,3,5...）
sed '2~2d' file.txt        # 偶数行删除（2,4,6...）
sed '0~3s/old/new/g' file.txt  # 每3行执行一次替换（3,6,9...）
```

### 4. 取反地址定位

语法：`地址!命令`

```Bash

sed '2,5!d' file.txt       # 除了2-5行，其他行全部删除
sed '/error/!d' file.txt   # 除了匹配error的行，其他行全部删除
```

### 5. 分组地址（多命令绑定）

对同一地址执行多个命令，用`{}`包裹，命令用分号分隔

```Bash

sed '/error/{s/ERROR/error/g;p;w error.log}' file.txt
# 匹配error的行：先替换大小写，再打印，最后写入error.log文件
```

## 五、核心编辑命令（高频必背）

按使用频率排序，覆盖99%日常场景，重点掌握替换命令。

### 5.1 替换命令 `s`（使用率70%+，核心中的核心）

语法：

```Bash

s/正则匹配模式/替换内容/标志位
```

核心说明：

- 分隔符`/`可自定义（`#` `@` `|`等），避免路径中`/`冲突

- 替换内容中可使用反向引用、特殊转义、匹配内容引用

#### 核心标志位flags

|标志位|核心作用|示例|
|---|---|---|
|`g`|全局替换，默认仅替换每行第一个匹配项|`sed 's/old/new/g' file` 替换每行所有old为new|
|`数字N`|替换每行第N个匹配项|`sed 's/old/new/3' file` 替换每行第3个old|
|`p`|打印替换成功的行，必须配合`-n`使用|`sed -n 's/old/new/gp' file` 仅输出替换后的行|
|`i/I`|匹配时忽略大小写|`sed 's/old/new/gi' file` 全局替换，忽略大小写|
|`w 文件名`|将替换成功的行写入指定文件|`sed 's/old/new/gw output.log' file`|
#### 替换进阶用法

1. 自定义分隔符（处理路径/URL）

```Bash

sed 's#/home/user#/opt/data#g' file.txt  # 用#替代/，避免路径转义
```

1. `&`引用匹配到的完整内容

```Bash

sed 's/[0-9]\+/(&)/g' file.txt  # 给所有数字加上括号，&代表匹配到的数字
sed 's/^.*$/【&】/g' file.txt    # 给每行内容加上【】包裹
```

1. 分组与反向引用

基础正则(BRE)中分组用`()`，扩展正则(ERE)用`()`，反向引用用`\1` `\2`...对应第N个分组

```Bash

# 示例：将 "name:张三 age:20" 转为 "张三:20"
sed 's/name:\(.*\) age:\(.*\)/\1:\2/g' file.txt
# 启用扩展正则，省去转义符
sed -E 's/name:(.*) age:(.*)/\1:\2/g' file.txt
```

1. 大小写转换（GNU sed特有）

|转义符|作用|
|---|---|
|`\U`|后面的字符全部转为大写，直到`\E`结束|
|`\L`|后面的字符全部转为小写，直到`\E`结束|
|`\u`|后面的第一个字符转为大写|
|`\l`|后面的第一个字符转为小写|
示例：

```Bash

sed 's/^[a-z]/\u&/g' file.txt  # 每行首字母大写
sed 's/[A-Z]/\l&/g' file.txt   # 所有大写字母转为小写
sed 's/\(.*\):\(.*\)/\U\1\E:\2/g' file.txt  # 冒号前的内容全部大写
```

### 5.2 删除命令 `d`

语法：`地址d`，删除匹配地址的行

```Bash

sed '2d' file.txt              # 删除第2行
sed '2,5d' file.txt            # 删除2-5行
sed '/^$/d' file.txt           # 删除纯空行
sed '/^[[:space:]]*$/d' file.txt  # 删除含空格/制表符的空行
sed '/^#/d' file.txt           # 删除#开头的注释行
sed '/error/d' file.txt        # 删除包含error的行
sed '1,/^END$/!d' file.txt     # 只保留1行到匹配END的行，其余全部删除
```

### 5.3 打印命令 `p`

语法：`地址p`，打印匹配地址的行，几乎都配合`-n`使用（避免重复输出）

```Bash

sed -n '2p' file.txt           # 仅打印第2行
sed -n '2,5p' file.txt         # 打印2-5行
sed -n '/error/p' file.txt     # 打印包含error的行（等效grep error）
sed -n '1~2p' file.txt         # 打印奇数行
sed -n '/start/,/end/p' file.txt  # 打印start到end之间的行
sed -n 'p;n' file.txt          # 打印奇数行，n读取下一行
sed -n 'n;p' file.txt          # 打印偶数行
```

### 5.4 追加/插入/整行替换命令

- `a\`：在匹配行**之后**追加文本

- `i\`：在匹配行**之前**插入文本

- `c\`：将匹配行**整行替换**为指定文本

```Bash

# 追加：第2行后追加"new line"
sed '2a\new line' file.txt
# 插入：匹配error的行前插入"=====ERROR START====="
sed '/error/i\=====ERROR START=====' file.txt
# 整行替换：第5行替换为"replaced line"
sed '5c\replaced line' file.txt
# 范围替换：2-4行全部替换为"=====CUT====="
sed '2,4c\=====CUT=====' file.txt
```

### 5.5 其他常用基础命令

|命令|核心作用|示例|
|---|---|---|
|`y`|按字符一一对应转换，类似tr命令|`sed 'y/abc/ABC/' file.txt` 小写a/b/c转大写|
|`r 文件名`|读取文件内容，追加到匹配行之后|`sed '$r footer.txt' file.txt` 末尾追加文件内容|
|`w 文件名`|将匹配行写入指定文件|`sed -n '/error/w error.log' file.txt` 提取错误日志|
|`=`|打印匹配行的行号|`sed -n '/error/=' file.txt` 打印含error行的行号|
|`q`|匹配到指定行后直接退出sed|`sed '5q' file.txt` 打印前5行后退出（等效head -5）|
|`n`|读取下一行到模式空间，覆盖当前内容|`sed '/error/{n;d}' file.txt` 删除匹配行的下一行|
## 六、sed正则表达式规范

sed默认使用**基础正则表达式(BRE)**，加`-E/-r`启用**扩展正则表达式(ERE)**，核心元字符差异如下：

|元字符|含义|BRE是否需要转义|ERE是否需要转义|
|---|---|---|---|
|`^`|行开头锚点|否|否|
|`$`|行结尾锚点|否|否|
|`.`|匹配任意单个字符|否|否|
|`*`|匹配前一个字符0次或多次|否|否|
|`+`|匹配前一个字符1次或多次|是(`+`)|否|
|`?`|匹配前一个字符0次或1次|是(`?`)|否|
|`{n,m}`|匹配前一个字符n到m次|是(`{n,m}`)|否|
|`()`|分组，用于反向引用|是(`()`)|否|
|`|`|或逻辑匹配|是(`|`)|
补充跨平台兼容规范：

- POSIX预定义字符类（全平台兼容）：`[[:digit:]]`（数字）、`[[:alpha:]]`（字母）、`[[:space:]]`（空白字符）、`[[:lower:]]`（小写）、`[[:upper:]]`（大写）

- 单词边界：GNU sed支持`\b`，BSD sed(macOS)需用`[[:<:]]`（单词开头）和`[[:>:]]`（单词结尾），跨平台优先用POSIX标准写法。

## 七、高级用法：模式空间+保持空间交互

sed的高级多行处理能力，核心是模式空间与保持空间的数据交互，核心交互命令如下：

|命令|核心作用|
|---|---|
|`h`|把模式空间内容**覆盖**写入保持空间|
|`H`|把模式空间内容**追加**到保持空间（加换行符）|
|`g`|把保持空间内容**覆盖**写入模式空间|
|`G`|把保持空间内容**追加**到模式空间（加换行符）|
|`x`|交换模式空间和保持空间的内容|
|`N`|读取下一行，追加到模式空间（用换行符分隔，合并多行）|
|`D`|删除模式空间中第一个换行符之前的内容，剩余内容继续执行命令|
|`P`|打印模式空间中第一个换行符之前的内容|
### 经典高级用法示例

1. 合并相邻两行（两行合并为一行，空格分隔）

```Bash

sed 'N;s/\n/ /' file.txt
```

1. 文本行反转（等效tac命令）

```Bash

sed '1!G;h;$!d' file.txt
# 解析：
# 1!G：除了第一行，都把保持空间内容追加到模式空间
# h：把模式空间内容覆盖到保持空间
# $!d：除了最后一行，都删除模式空间内容，不输出
```

1. 打印匹配内容的前后行

```Bash

sed -n '/error/{N;p}' file.txt   # 打印匹配行和下一行
sed -n '/error/{x;p;x;p}' file.txt  # 打印匹配行和上一行
```

1. 给所有行加上行号

```Bash

sed = file.txt | sed 'N;s/\n/ /'
```

## 八、生产级实战案例

1. 批量修改配置文件（安全备份+替换）

```Bash

# 替换配置文件中port=8080为port=9090，先备份为.ini.bak
sed -i.bak 's/^port=8080$/port=9090/g' app.ini
```

1. 清理配置文件（删除空行+注释行）

```Bash

sed -i.bak -e '/^#/d' -e '/^[[:space:]]*$/d' nginx.conf
```

1. 批量重命名文件（配合xargs）

```Bash

# 将所有.txt文件改为.md文件
ls *.txt | sed 's/\(.*\)\.txt/mv & \1.md/' | bash
```

1. 提取HTML中的链接

```Bash

sed -n 's/.*href="\([^"]*\)".*/\1/p' index.html
```

1. 批量给行首尾加标签包裹

```Bash

# 给每行内容加上<p>和</p>包裹
sed 's/^.*$/<p>&<\/p>/g' index.html
```

## 九、避坑指南与最佳实践

### 9.1 新手致命坑

1. `-i`直接修改原文件无撤回：执行前必须先用不带`-i`的命令测试输出，确认无误再加`-i`，优先用`-i.bak`备份

2. 替换不加`g`只改第一个匹配：默认`s/old/new/`仅替换每行第一个匹配项，全局替换必须加`g`

3. 正则元字符未转义：匹配`.` `*` `?` `^` `$` `/`等字面量时，必须加`\`转义，或换用自定义分隔符

4. 二进制文件修改：sed仅适用于纯文本文件，修改压缩包、图片、可执行文件会直接损坏文件

### 9.2 跨平台兼容性坑（GNU sed vs BSD sed）

|特性|GNU sed(Linux)|BSD sed(macOS/FreeBSD)|兼容写法|
|---|---|---|---|
|`-i`无备份|`sed -i 's/old/new/g' file`|必须指定后缀，无备份写`sed -i '' 's/old/new/g' file`|用`-i.bak`生成备份，兼容所有平台|
|单词边界|支持`\b`|不支持`\b`，需用`[[:<:]]`和`[[:>:]]`|用POSIX标准`[[:<:]]word[[:>:]]`|
|扩展正则|`-r`/`-E`等效|优先用`-E`|统一用`-E`启用扩展正则|
### 9.3 性能优化最佳实践

1. 避免循环调用sed：批量处理多个文件，直接`sed '命令' *.txt`，不要在for循环中逐个调用sed

2. 合并多个命令：多个操作合并为一个sed命令，用`-e`或`{}`组合，避免多次读取文件

3. 提前退出：处理到指定行即可退出，比如打印前10行用`sed '10q' file`，比`sed -n '1,10p' file`效率更高

4. 大文件加速：用`LC_ALL=C sed '命令' file`关闭本地化校验，大幅提升正则匹配速度

## 十、高频命令速查表

|场景|命令|
|---|---|
|全局文本替换|`sed 's/old/new/g' file`|
|仅打印匹配行|`sed -n '/pattern/p' file`|
|删除纯空行|`sed '/^$/d' file`|
|删除注释行+空行|`sed -e '/^#/d' -e '/^[[:space:]]*$/d' file`|
|打印前N行|`sed 'Nq' file`|
|行尾追加内容|`sed 's/$/追加内容/g' file`|
|行首添加内容|`sed 's/^/添加内容/g' file`|
|反转行顺序|`sed '1!G;h;$!d' file`|
|打印文件最后一行|`sed -n '$p' file`|
> （注：文档部分内容可能由 AI 生成）
