✸ ✸ ✸
sed 替换基础语法
sed(Stream Editor)是 Linux 下最强大的文本处理工具之一。它的替换功能用得最多,核心语法:
sed 's/旧字符串/新字符串/标志' 文件名
其中 s 表示替换(substitute),标志位控制替换行为。
替换标志详解
| 标志 | 含义 | 示例 |
|---|---|---|
| 无标志 | 只替换每行第一个匹配 | sed 's/a/b/' file |
g | 替换每行所有匹配(全局) | sed 's/a/b/g' file |
i | 忽略大小写 | sed 's/hello/world/gi' file |
2 | 只替换每行第2个匹配 | sed 's/a/b/2' file |
p | 打印替换后的行 | sed -n 's/a/b/p' file |
-i 参数:直接修改文件
默认 sed 只输出结果不改文件。加 -i 直接修改原文件(危险操作,建议先备份):
# 直接修改文件(Linux)
sed -i 's/https/http/g' config.txt
# macOS 需要指定备份后缀(空字符串表示不备份)
sed -i '' 's/https/http/g' config.txt
# 建议:先备份再替换
sed -i.bak 's/https/http/g' config.txt # 自动生成 config.txt.bak
批量替换多个文件
结合 find 命令,可以递归替换目录下所有匹配文件:
# 替换当前目录下所有 .conf 文件中的 https 为 http
sed -i 's/https/http/g' $(find ./ -name '*.conf')
# 更安全的写法(处理文件名含空格的情况)
find ./ -name '*.conf' -exec sed -i 's/https/http/g' {} \;
# 或者用 xargs(性能更好)
find ./ -name '*.conf' | xargs sed -i 's/https/http/g'
# 只替换 .py 文件中的 print 语句
find ./ -name '*.py' -exec sed -i 's/print \(.*\)/print(\1)/g' {} \;
高级用法
使用不同的分隔符
当替换内容包含 / 时,可以用其他字符做分隔符:
# 替换路径中的 / 很麻烦
sed -i 's/\/usr\/local\/bin/\/opt\/bin/g' file
# 用 # 或 | 做分隔符,清爽很多
sed -i 's#/usr/local/bin#/opt/bin#g' file
sed -i 's|/usr/local/bin|/opt/bin|g' file
正则表达式替换
# 删除行首空格
sed -i 's/^[ \t]*//' file
# 删除空行
sed -i '/^$/d' file
# 删除注释行(# 开头)
sed -i '/^#/d' file
# 在每行末尾加分号
sed -i 's/$/ ;/' file
# 提取 IP 地址所在行
sed -n '/[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/p' file
指定行范围替换
# 只替换第3行
sed -i '3s/old/new/g' file
# 替换第2到5行
sed -i '2,5s/old/new/g' file
# 替换最后一行
sed -i '$s/old/new/g' file
# 从匹配行开始替换到文件末尾
sed -i '/START/,$s/old/new/g' file
多条替换命令
# 用 -e 串联多条命令
sed -i -e 's/foo/bar/g' -e 's/hello/world/g' file
# 或者用分号
sed -i 's/foo/bar/g; s/hello/world/g' file
实战场景
场景1:批量修改配置文件中的域名
# 迁移服务器时批量替换域名
find /etc/nginx/conf.d/ -name '*.conf' \
-exec sed -i 's/old-domain.com/new-domain.com/g' {} \;
# 验证替换结果
grep -r 'old-domain.com' /etc/nginx/conf.d/ # 应该无输出
grep -r 'new-domain.com' /etc/nginx/conf.d/ # 确认新域名
场景2:修改 MySQL 配置
# 修改 max_connections
sed -i 's/^max_connections.*/max_connections = 500/' /etc/my.cnf
# 如果配置项不存在则追加
grep -q 'max_connections' /etc/my.cnf || echo 'max_connections = 500' >> /etc/my.cnf
场景3:处理 CSV 数据
# 将 CSV 的逗号分隔改为 Tab 分隔
sed -i 's/,/\t/g' data.csv
# 删除 CSV 第一行(表头)
sed -i '1d' data.csv
# 在第一行前插入新表头
sed -i '1i\id,name,email,phone' data.csv
sed 替换流程
读取一行 --> 模式匹配? --是--> 执行替换 --> 输出结果
| |
否 有 -i ?
| / \
直接输出 是 否
| |
写回文件 输出到终端
常见踩坑
sed -i在 macOS 和 Linux 上行为不同,macOS 必须加备份后缀参数- 替换内容包含
&时需要转义(\&),因为&在 sed 中代表匹配到的内容 - 使用变量时要用双引号:
sed -i "s/$OLD/$NEW/g" file - 处理大文件时
sed -i会创建临时文件,确保磁盘空间充足
总结
sed 替换的核心就是 s/old/new/g 加 -i。配合 find 做批量替换,配合正则做复杂匹配,基本能覆盖日常 90% 的文本处理需求。
✸ ✸ ✸


📜 留言板
留言提交后需管理员审核通过才会显示