🔍搜索⌘K

Linux 下 sed 命令的核心用法与实战指南

概述

sed(Stream Editor,流编辑器)是 Linux 系统中一款高效的文本处理工具,其核心能力是通过脚本指令自动化处理文本文件,无需手动打开编辑界面即可完成批量修改、过滤、转换等操作。

根据 man 手册的官方定义,sed 是 “stream editor for filtering and transforming text”,即用于过滤和转换文本的流编辑器。它的典型应用场景包括:

  • 自动编辑单个或多个文本文件
  • 简化对文件的重复性操作(如批量替换固定字符)
  • 编写文本格式转换程序(如日志格式标准化)
  • 配合管道(|)处理其他命令的输出结果

sed 核心参数解析

sed 的参数用于控制命令的执行模式,常用核心参数如下表所示,清晰区分参数作用与使用场景:

参数完整写法核心作用适用场景
-n-抑制模式空间的自动打印仅显示匹配或处理后的内容(需配合 p 命令)
-e—expression=script多点编辑一次执行多个 sed 命令(如同时删除 + 替换)
-f—file=/PATH/TO/SCRIPT从文件读取命令命令较多时,将指令写入脚本文件批量执行
-r—regexp-extended支持扩展正则表达式无需对 +、?、() 等符号转义(同 -E)
-i—in-place[=SUFFIX]直接编辑原文件需修改源文件时使用(加后缀可备份,如 -i.bak)

sed 地址:定位要处理的行

sed 通过 “地址” 指定需要处理的文本行,地址格式决定了操作的范围,是精准处理文本的关键。

地址类型格式示例作用说明
空地址无对文件所有行执行操作
单地址5仅处理第 5 行
单地址/error/处理所有包含 “error” 模式(正则匹配)的行
地址范围3,7处理第 3 行到第 7 行(含首尾)
地址范围5,+3处理第 5 行及后续 3 行(共 4 行:5/6/7/8)
地址范围2,/EOF/从第 2 行开始,直到匹配 “EOF” 的行结束
地址范围/start/,/end/从匹配 “start” 的行开始,到匹配 “end” 的行结束
地址范围$仅处理文件的最后一行($ 表示行尾)
步进(间隔)1~2处理所有奇数行(从第 1 行开始,步长 2)
步进(间隔)2~2处理所有偶数行(从第 2 行开始,步长 2)

sed 基础命令:实现核心操作

sed 命令需配合 “地址” 使用,定义对定位行的具体操作,常用基础命令如下:

命令语法格式作用说明
d[地址]d删除定位到的行(不保留到输出)
p[地址]p打印模式空间中的内容(需配合 -n 抑制默认输出)
a[地址]a \text在定位行后面追加文本 “text”,支持 \n 换行(如 a hello\nworld)
i[地址]i \text在定位行前面插入文本 “text”,支持 \n 换行
c[地址]c \text用 “text”替换定位到的所有行(整行替换)
w[地址]w /PATH/FILE将定位到的行保存到指定文件(覆盖原文件内容)
r[地址]r /PATH/FILE读取指定文件的内容,追加到定位行后面(实现文件合并)
=[地址]=为定位到的行打印行号(单独输出在行首)
![地址]!命令条件取反:对 “不满足地址” 的行执行命令(如 /error/!d 表示 “除含 error 的行外都删除”)
s[地址]s/原内容/新内容/标记查找替换(核心命令),分隔符可自定义(如 s@@@、s###)

替换命令(s)的关键标记

替换命令 s/// 是 sed 最常用的功能,通过 “标记” 扩展灵活性,常用标记如下:

  • g:全局替换(默认仅替换每行第一个匹配项)
  • w /PATH/FILE:将替换成功的行保存到指定文件
  • p:显示替换成功的行(需配合 -n)
  • i:忽略大小写匹配(如 s/error/INFO/gi 表示全局忽略大小写替换)

此外,替换中可使用特殊符号:

  • &:表示匹配到的完整内容(如 s/int/&eger/g 会将 “int” 替换为 “integer”)
  • \n(n 为数字):引用正则中 () 捕获的第 n 个分组(如 s/(name):(\w+)/\2=\1/ 会将 “name:Tom” 替换为 “Tom=name”)

sed 高级命令:模式空间与保持空间

sed 内部维护两个缓存区:模式空间(Pattern Space) 和 保持空间(Hold Space)。模式空间用于临时存储当前处理的行,保持空间用于暂存数据,高级命令通过操作这两个空间实现复杂文本处理(如跨行处理、数据暂存)。

命令作用说明
h将模式空间的内容覆盖到保持空间(原保持空间内容被清空)
H将模式空间的内容追加到保持空间(原内容后加换行符)
g将保持空间的内容覆盖到模式空间(原模式空间内容被清空)
G将保持空间的内容追加到模式空间(原内容后加换行符)
x交换模式空间与保持空间的内容
n读取下一行文本覆盖到模式空间(替换当前行,跳过后续命令)
N读取下一行文本追加到模式空间(形成多行模式空间,可跨行处理)
d删除模式空间中的所有内容(终止当前循环,读取下一行)
D仅删除多行模式空间中的第一行(不终止循环,可继续处理剩余内容)

提示:高级命令需结合实际场景理解,例如用 N+D 可实现 “删除空行”“合并多行” 等操作。

sed 实战示例:从基础到进阶

以下示例覆盖日常工作中最常用的 sed 场景,所有示例均使用变量(如 $pattern、$path_to_file)表示动态内容,实际使用时需替换为具体值(如 /var/log/nginx.log)。

1. 精准查看指定内容(抑制自动打印)

通过 -n+p 仅显示匹配的行,避免输出冗余内容:

# 显示包含指定模式的行
sed -n "/$pattern/p" $path_to_file
# 显示两个模式之间的所有行
sed -n "/$start_pattern/,/$end_pattern/p" $path_to_file
# 显示指定行
sed -n "${line_num}p" $path_to_file
# 显示行范围
sed -n "$from_line,$to_line)p" $path_to_file

2. 批量删除指定行

删除操作不修改原文件(除非加 -i),仅输出处理后的结果:

# 删除第 N 行
sed "${line_num}d" $path_to_file
# 删除所有包含指定模式的行
sed "/$pattern/d" $path_to_file
# 删除最后一行
sed "$d" $path_to_file

3. 插入与替换行(整行操作)

3.1 在指定行后追加内容

# 在第 N 行后追加文本
sed "${line_num}a\ $content" $path_to_file
# 在包含模式的行后追加文本(支持换行)
sed "/$pattern/a hello\nworld" $path_to_file

3.2 在指定行前插入内容

# 在第 N 行前插入文本
sed "${line_num}i\ $content" $path_to_file
# 在包含模式的行前插入文本
sed "/$pattern/i $content" $path_to_file

3.3 替换指定行(整行替换)

# 用内容替换第 N 行
sed "${line_num}c\ $new_content" $path_to_file
# 用内容替换所有包含模式的行
sed "/$pattern/c\ $new_content" $path_to_file

4. 合并文件:插入外部文件内容

通过 r 命令将外部文件内容插入到指定位置:

# 在每一行后插入外部文件内容
sed "r $external_file" $target_file
# 在第 N 行后插入外部文件内容
sed "${line_num}r $external_file" $target_file
# 在指定行范围后插入外部文件内容
sed "$from_line,$to_line r $external_file" $target_file

5. 保存处理结果到新文件

5.1 保存匹配行到新文件

# 将包含模式的行保存到新文件(原文件不变)
sed -n "/$pattern/w $new_file" $source_file

5.2 直接修改原文件(带备份)

# 直接修改原文件,并备份为 “原文件.bak”
sed -i.bak "s/$old/$new/g" $target_file

6. 查找替换:从基础到高级

6.1 基础替换(全局替换)

# 全局替换文件中所有 “old” 为 “new”
sed "s/$old/$new/g" $target_file

6.2 指定行替换

# 仅在第 N 行替换 “old” 为 “new”
sed "${line_num}s/$old/$new/g" $target_file
# 仅在包含模式的行中替换(忽略大小写)
sed "/$pattern/s/$old/$new/gi" $target_file

6.3 引用匹配内容(& 与分组)

# 用 & 引用匹配的完整内容(给 “link” 后加 “er”)
sed 's/link/&er/g' $file
# 用 \1 引用分组内容(交换 “name:value” 为 “value=name”)
sed 's/\(name\):\(.*\)/\2=\1/g' $file

7. 扩展用法:多点编辑与脚本执行

7.1 一次执行多个命令(多点编辑)

通过 -e 实现 “删除 + 插入” 组合操作:

# 1. 在第 1 行前插入文本;2. 在第 1 行后追加文本
sed -e "1i $insert_content" -e "1a $append_content" $file

7.2 从脚本文件执行命令

当命令较多时,将指令写入脚本文件(如 sed_script.sed):

# sed_script.sed 内容示例
# 1d          # 删除第 1 行
# s/error/INFO/g  # 全局替换 error 为 INFO
# /EOF/w result.txt # 将包含 EOF 的行保存到 result.txt

# 执行脚本文件
sed -f $sed_script $target_file

8. 配合正则:扩展正则的使用

通过 -r(或 -E)支持扩展正则,无需转义特殊符号:

# 匹配 “error” 或 “warn”(扩展正则的 “|” 无需转义)
sed -r -n "/error|warn/p" $log_file
# 匹配 “num” 后跟 1-3 个数字(扩展正则的 “{n,m}” 无需转义)
sed -r "s/num([0-9]{1,3})/number\1/g" $file

总结

sed 作为 Linux 文本处理的核心工具,其优势在于自动化、高效性和灵活性。掌握 “地址定位 + 命令操作” 的核心逻辑后,可轻松应对批量文本修改、日志过滤、格式转换等场景。

建议从基础命令(s/d/p)和示例入手,熟悉后再探索模式空间与保持空间的高级用法,逐步将 sed 融入日常工作流,提升文本处理效率。