sed 命令用法解析
一、概述
sed(Stream Editor,流编辑器)是Unix/Linux系统中强大的文本处理工具,主要用于对文本进行查找、替换、插入、删除等操作。其核心特点是:
- 流式处理:逐行读取输入(文件或管道数据),按指定规则处理后输出。
- 非破坏性:默认仅修改输出内容,不改变原始文件(需
-i选项强制修改)。 - 支持正则:结合正则表达式实现复杂模式匹配,支持基础正则和扩展正则(需
-r选项)。
二、基本语法
sed [选项] '指令' [文件...]
常用选项
| 选项 | 作用 |
|---|---|
-n |
抑制默认输出(仅打印匹配/处理的行) |
-i |
直接修改原始文件(建议配合备份:-i.bak保留原文件为.bak) |
-r |
启用扩展正则表达式(无需转义`(){}?+ |
-e |
支持多个指令组合执行 |
三、核心功能与示例
1. 查找(打印特定内容)
通过-n(抑制默认输出)和p(打印)指令实现精准查找,支持行号匹配和内容匹配。
(1)按行号查找
# 打印第2行
sed -n '2p' test.txt
# 打印第2-5行
sed -n '2,5p' test.txt
# 打印第2行和第5行(分号分隔多个指令)
sed -n '2p;5p' test.txt
(2)按内容查找
# 打印包含"ccc"的行
sed -n '/ccc/p' test.txt
# 打印从"aaa"首次出现到"ccc"首次出现之间的行
sed -n '/aaa/,/ccc/p' test.txt
# 同时打印包含"aaa"和"ccc"的行
sed -n '/aaa/p;/ccc/p' test.txt
2. 新增(插入/追加文本)
通过i(行前插入)、a(行后追加)、c(替换整行)指令添加内容。
(1)指定行位置新增
# 在第1行前插入"why"
sed '1iwhy' test.txt
# 在最后一行前插入"why"($表示末尾)
sed '$iwhy' test.txt
# 在最后一行后追加"why"
sed '$awhy' test.txt
# 将第2行替换为"why"
sed '2cwhy' test.txt
(2)匹配内容位置新增
# 在包含"222"的行前插入"why"
sed '/222/iwhy' test.txt
# 在包含"333"的行后追加"why"
sed '/333/awhy' test.txt
# 多指令组合:在"222"前插、"333"后插(-e支持多指令)
sed -e '/222/iwhy' -e '/333/awhy' test.txt
(3)新增多行内容
通过\n换行符实现多行插入:
# 在"222"行后追加"why"和"123"(分行)
sed '/222/awhy\n123' test.txt
3. 删除(移除指定行)
通过d(删除)指令移除行,支持行号范围和内容匹配。
# 删除第2-5行
sed '2,5d' test.txt
# 删除第2行和第5行
sed '2d;5d' test.txt
# 删除包含空行(^$表示空行)
sed '/^$/d' test.txt
# 删除注释行(以#开头)
sed '/^#/d' test.txt
4. 修改(替换文本)
通过s(替换)指令实现文本替换,语法:s#原内容#新内容#选项(分隔符可换为/或|)。
(1)普通替换
# 将"old"替换为"new"(仅替换每行第一个匹配)
sed 's#old#new#' test.txt
# 全局替换(g选项:替换每行所有匹配)
sed 's#old#new#g' test.txt
# 示例:移除IP地址中的子网掩码(如192.168.0.102/24 → 192.168.0.102)
ip a s wlo1 | sed -n '4p' | sed 's#/.*##g'
(2)后项引用(正则分组替换)
用()捕获分组,\1、\2等引用分组内容(需-r启用扩展正则),语法:sed 's#(正则)#\n#g':
# 提取 IP 地址(从"inet 192.168.0.102/24..."中取 IP)
# (.*)捕获 IP 部分,\1 引用该部分作为替换结果,& 表示替换的内容
ip a s wlo1 | sed -n '4p' | sed -r 's#^.*inet (.*)/.*#\1#g'
(3)自动备份替换
修改原始文件时,通过-i.bak保留备份:
# 替换"eee"为"fff",同时备份原文件为test02.bak
sed -i.bak 's#eee#fff#g' test02
(4)注意:危险操作
-n(抑制输出)与-i(修改文件)同时使用会清空文件,需避免:
# 错误示例:会清空test02.bak
sed -ni 's#fff#kkk#g' test02.bak
四、扩展用法(实战场景)
1. 批量修改文件名
结合管道和bash执行生成的命令:
# 将所有.bak文件改名为.txt(& 表示匹配的原文件名)
ls *.bak | sed -r 's#(.*)\.bak#mv & \1.txt#g' | bash
2. 过滤有效内容(非空+非注释行)
# 同时删除空行和注释行
sed -r '/^$/d;/^#/d' line.txt
3. 批量添加前缀/后缀
# 每行开头加"HEAD "
sed 's/^/HEAD &/g' line.txt
# 每行结尾加" TAIL"
sed 's/$/ TAIL/g' line.txt
4. 提取本机IP地址
# 从网卡wlo1中提取IPv4地址
ip a s wlo1 | sed -r -n '4s#^.*inet (.*)/.*#\1#gp'
五、注意事项
- 默认不修改原文件:无
-i时仅输出到终端,需重定向保存(sed ... > new.txt)。 - 正则转义:使用基础正则时,
(){}?+|需加\转义;-r模式下可直接使用。 - 备份重要:使用
-i修改文件前,建议用-i.bak备份(修改后可删除.bak)。 - 多行处理:sed按行处理,复杂多行逻辑需结合
N(合并行)等高级指令。