一、基本概念与语法
sed(Stream Editor)是 Linux/Unix 系统中强大的文本处理工具,它通过正则表达式对文本进行批量编辑(替换、删除、插入等)。与交互式编辑器不同,sed 通过命令行参数或脚本一次性完成所有编辑操作。
基本语法格式
sed [选项] '命令' 输入文件
常用选项详解:
- -i:直接修改原文件(谨慎使用),建议配合备份使用:
sed -i.bak 's/old/new/' file.txt # 修改原文件并创建备份file.txt.bak
- -e:允许多个编辑命令串联使用:
sed -e 's/foo/bar/' -e 's/hello/world/' file.txt
- -n:静默模式,仅输出被处理的行(需配合p命令):
sed -n '1,5p' file.txt # 只打印1-5行
常见命令分类:
- 文本转换:
s
:替换(Substitute)y
:字符转换(类似tr)
- 行操作:
d
:删除(Delete)p
:打印(Print)a
:追加(Append)i
:插入(Insert)c
:更改(Change)
- 文件操作:
r
:读取外部文件w
:写入外部文件
二、核心功能详解与示例
1. 文本替换(s命令)
替换命令是sed最常用的功能,语法为s/pattern/replacement/flags
基础替换:
# 替换所有"apple"为"orange"(全局替换)
sed 's/apple/orange/g' fruits.txt
# 仅替换每行第一个匹配项(不加g标志)
sed 's/apple/orange/' fruits.txt
范围限定替换:
# 替换第2行到第5行的"apple"为"orange"
sed '2,5s/apple/orange/g' fruits.txt
# 替换包含"fruit"的行中的"apple"为"orange"
sed '/fruit/s/apple/orange/g' fruits.txt
# 只替换不以"#"开头的行中的"http"为"https"
sed '/^[^#]/s/http/https/g' urls.txt
特殊字符处理:
# 当替换内容含斜杠时,可使用其他分隔符
sed 's#/usr/local#/opt#g' paths.txt
sed 's|http://|https://|g' urls.txt
# 替换路径中的特殊字符需要转义
sed 's/\/home\/user/\/data\/user/g' config.txt
2. 行删除(d命令)
# 删除第3行
sed '3d' data.txt
# 删除空行(包括可能含空格/TAB的空行)
sed '/^[[:space:]]*$/d' file.txt
# 删除包含"error"或"ERROR"的行(不区分大小写)
sed '/error/Id' log.txt
# 删除注释行(以#或//开头)
sed '/^[#\/\/]/d' config.txt
# 删除从匹配"start"到匹配"end"之间的所有行
sed '/start/,/end/d' file.txt
3. 内容插入与追加
# 在第2行后追加一行"new line"
sed '2a new line' input.txt
# 在第1行前插入多行内容(使用\n分隔)
sed '1i header line1\nheader line2' file.txt
# 在所有包含"data"的行后追加文件内容
sed '/data/r additional.txt' main.txt
# 在文件末尾追加内容
sed '$a \n--- END OF FILE ---' document.txt
4. 行打印控制
# 仅打印第3行(静默模式+打印命令)
sed -n '3p' data.txt
# 打印包含"error"的行及其后2行
sed -n '/error/,+2p' log.txt
# 打印从"BEGIN"到"END"标记之间的内容
sed -n '/BEGIN/,/END/p' document.txt
# 打印行号(GNU sed特有)
sed '=' file.txt | sed 'N;s/\n/ /'
5. 高级正则表达式应用
# 替换所有数字为"NUM"
sed 's/[0-9]/NUM/g' input.txt
# 替换IP地址中的最后一位为"x"
sed 's/\.[0-9]\{1,3\}$/.x/g' ips.txt
# 提取email地址(简化版)
sed -n 's/.*\([a-zA-Z0-9._%+-]\+@[a-zA-Z0-9.-]\+\.[a-zA-Z]\{2,\}\).*/\1/p' contacts.txt
# 格式化日期从MM/DD/YYYY到YYYY-MM-DD
sed 's#\([0-9]\{2\}\)/\([0-9]\{2\}\)/\([0-9]\{4\}\)#\3-\1-\2#g' dates.txt
三、进阶技巧与应用
1. 多行处理
# 合并相邻空白行为单行空行
sed '/^$/{N;/^\n$/D}' file.txt
# 在每5行后插入分隔线
sed '0~5a \-----' longfile.txt
# 删除HTML标签(简化版)
sed 's/<[^>]*>//g' page.html
2. 变量与脚本集成
# 使用环境变量
old_word=$1
new_word=$2
sed "s/$old_word/$new_word/g" input.txt > output.txt
# 从文件中读取替换模式
sed -f script.sed input.txt
其中script.sed内容示例:
s/apple/orange/g
/error/d
1,5s/foo/bar/
3. 分支与流程控制
# 对匹配行执行多条命令
sed '/pattern/{
s/foo/bar/
s/hello/world/
}' file.txt
# 跳过某些行的处理
sed '/skip/!s/old/new/g' file.txt
四、实用场景案例
1. 系统管理
# 批量修改SSH配置
sed -i 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
# 清除日志中的敏感信息
sed -i '/password/d;/credit_card/d' access.log
2. 数据处理
# CSV文件处理:替换分隔符
sed 's/,/|/g' data.csv
# 提取日志时间戳
sed -n 's/^\[\(.*\)\].*/\1/p' server.log
# 生成SQL INSERT语句
sed "s/\(.*\),\(.*\)/INSERT INTO table VALUES('\1','\2');/" data.txt
3. 代码处理
# 批量更新版权年份
sed -i 's/Copyright 2000-20[0-9][0-9]/Copyright 2000-2023/g' *.py
# Python代码注释转换
sed -i '/^# /s/# /\/\//' *.py # # → //
五、注意事项与最佳实践
-
备份策略:
# 安全修改模式(GNU sed) sed -i.bak 's/old/new/' file.txt # macOS BSD sed版本 sed -i '' 's/old/new/' file.txt
-
性能优化:
- 对大型文件使用
-u
选项(无缓冲模式) - 多个编辑操作尽量合并到一个sed命令中
- 对大型文件使用
-
跨平台兼容:
# GNU sed与BSD sed差异处理 if [[ "$(uname)" == "Darwin" ]]; then sed -i '' 's/old/new/' file.txt else sed -i 's/old/new/' file.txt fi
-
调试技巧:
# 先测试不修改原文件 sed 's/pattern/replacement/' file.txt # 显示行号辅助调试 sed 's/old/new/' file.txt | nl
通过掌握这些sed的高级用法,可以显著提高文本处理效率。建议通过info sed
(GNU系统)或man sed
查看完整文档,并逐步积累实际使用经验。