Shell 的 sed 命令详解(新手详细版)
本文档面向零基础新手,从“sed 是干什么的”讲起,详细说明基本概念、寻址、替换、删除、插入、常用选项、正则与转义、实用示例等,并配有大量示例。
一、sed 是什么?
1.1 一句话理解
sed(Stream EDitor)是流式编辑器:对输入一行一行处理,按你给的“命令”做查找、替换、删除、插入等,再把结果输出。
默认不修改原文件,只把结果打印到标准输出;要改文件需用 -i 选项。
- 流式:按行读入、按行处理、按行输出,适合管道和脚本。
- 编辑器:能做替换、删行、插行等“编辑”操作。
1.2 典型用途
- 批量替换文件里的字符串(如改配置、改路径);
- 删除某些行(如空行、注释行);
- 插入或追加几行(如在某行前/后加内容);
- 和管道配合,对命令输出做简单“清洗”。
二、基本语法
sed [选项] '脚本' [输入文件...]
- 脚本:由一个或多个命令组成,告诉 sed 对“哪几行”做“什么操作”。
- 输入:不写文件则从标准输入读(管道或键盘)。
- 常见写法:
sed 's/旧/新/' file.txt(把每行里第一次出现的“旧”换成“新”)。
示例:
# 把 file.txt 里每行第一个 hello 换成 hi,结果打印到屏幕
sed 's/hello/hi/' file.txt
# 从管道读
echo "hello world" | sed 's/hello/hi/'
# 输出:hi world
# 不写文件 = 从标准输入
sed 's/foo/bar/'
# 然后输入几行,每行回车后看到替换结果
三、核心概念:寻址 + 命令
3.1 寻址(对哪几行生效)
sed 的很多命令可以带寻址:只对满足条件的行执行命令。不写寻址就表示每一行。
| 寻址写法 | 含义 | 示例 |
|---|---|---|
| 无 | 每一行 | sed 's/a/b/' |
n |
第 n 行(n 为数字) | sed '3s/a/b/' 只改第 3 行 |
$ |
最后一行 | sed '$s/a/b/' |
n,m |
第 n 到 m 行 | sed '2,5s/a/b/' |
n,+k |
第 n 行及后面 k 行(部分 sed 支持) | sed '2,+3s/a/b/' |
/模式/ |
包含该模式的行 | sed '/error/s/old/new/' |
n,m! 或 ! |
对“不匹配”的行执行(取反) | sed '3!s/a/b/' 除第 3 行外都替换 |
示例:
# 只替换第 2 行里的 first 为 second
sed '2s/first/second/' file.txt
# 只替换第 1 到 5 行
sed '1,5s/old/new/' file.txt
# 只替换包含 "apple" 的行
sed '/apple/s/red/green/' file.txt
# 只删除第 3 行
sed '3d' file.txt
# 删除最后一行
sed '$d' file.txt
3.2 常用命令(做什么)
| 命令 | 含义 | 示例 |
|---|---|---|
s/旧/新/ |
替换:把“旧”换成“新”(每行默认只换第一次) | sed 's/foo/bar/' |
d |
删除该行(不输出) | sed '3d'、sed '/^#/d' |
p |
打印该行(常与 -n 一起用,只打印匹配的) | sed -n '3p' |
a 文本 |
在该行后面追加一行 | sed '2a hello' |
i 文本 |
在该行前面插入一行 | sed '2i hello' |
c 文本 |
用“文本”整行替换该行 | sed '2c new line' |
y/源字符集/目标字符集/ |
按字符一一替换(类似 tr) | sed 'y/abc/ABC/' |
下面按“替换、删除、打印、插入/追加、y”分开细讲。
四、替换命令 s(最常用)
4.1 基本形式
s/要替换的内容/替换成什么/[标志]
- 默认只替换每行里第一次出现的那一处。
- 分隔符不一定是
/,可以是别的(如#、|),只要三个一致即可,便于替换路径等含/的字符串。
示例:
# 每行第一个 hello 换成 hi
sed 's/hello/hi/' file.txt
# 分隔符用 #,适合内容里有很多 /
sed 's#/old/path#/new/path#' file.txt
# 替换 192.168.1.1 为 10.0.0.1(点要转义,见下节)
sed 's/192.168.1.1/10.0.0.1/' file.txt
4.2 替换标志(放在最后一格)
| 标志 | 含义 |
|---|---|
g |
全局:该行所有匹配都替换,不只第一个 |
i 或 I |
忽略大小写(GNU sed) |
p |
若该行发生替换,则打印该行(常与 -n 一起用) |
数字 |
只替换第 n 次出现,如 s/old/new/2 |
w 文件 |
把发生替换的行写入指定文件(GNU sed) |
示例:
# 把所有 hello 都换成 hi
sed 's/hello/hi/g' file.txt
# 只替换每行第 2 个 old 为 new
sed 's/old/new/2' file.txt
# 忽略大小写
sed 's/hello/hi/gi' file.txt
4.3 正则、& 和反向引用 1 2
- 要替换的内容里可以用正则;替换成什么里可以用:
- &:代表“本次匹配到的整段内容”;
- 1、2、…:代表前面用
(...)括起来的第 1、2、… 组。