Sed
章节大纲
-
sed(流编辑器)简介
sed(stream editor,流编辑器)是 Unix 系统中的一个文本处理工具,可用于解析和转换文本文件,且支持多个操作系统。尽管在许多用途上已经被perl(或更早的AWK)取代,但sed在 Shell 脚本中的简单文本转换仍然有一定的应用价值。sed是面向行(line-oriented)的,它逐行处理输入,支持正则表达式匹配和替换。
1. sed 的基本使用
1.1
s(substitution,替换)命令sed最常用的功能是s命令(替换),用于将一种模式替换为另一种模式,例如:sed 's/cat/dog/g' input.txt > output.txt以上命令会将
input.txt中的"cat"替换为"dog",并输出到output.txt。其中:s/cat/dog/:将cat替换为dogg(global):表示替换行内所有匹配项,而不仅仅是第一个
建议:使用单引号
''避免 Shell 误解析特殊字符:sed 's/cat/dog/g' input.txt > output.txt
1.2 多个替换
可以使用
-e选项进行多个模式替换:sed -e 's/cat/dog/g' -e 's/meow/woof/g' input.txt > output.txt
1.3
sed作为管道处理sed也可用于管道操作:echo "Hello cat" | sed 's/cat/dog/g'输出:
Hello dog
2. 复杂模式匹配
2.1 扩展正则表达式
默认情况下,
sed仅支持基本正则表达式(BRE),如需使用扩展正则表达式(ERE),需要:- GNU sed 使用
-r - BSD sed(macOS 默认安装) 使用
-E
示例:
sed -r 's/<(.*)>/<\1><\/\1>/g' input.txt以上命令会将
<a>替换为<a></a>。
2.2 组匹配与替换
使用
()进行分组匹配,并在替换中使用\1, \2, ...引用:echo "abc" | sed -r 's/(a)(b)(c)/\3\2\1/'输出:
cba
3. 编程与高级用法
3.1 逐行操作
sed逐行处理数据,每次仅处理一行。如需跨行操作,可使用:N(读取下一行到缓冲区)H和g(存入/获取缓冲区)
3.2 合并多行
tr命令比sed更适合合并所有行:tr '\n' ' ' < input.txt > output.txttr逐字符处理,不会占用大量内存,而sed会加载整个文件到内存。
4. 相关命令
grep:选择符合条件的行tr:进行单字符转换awk和perl:处理复杂文本任务
5. sed 选项
5.1 POSIX
sed选项-n # 仅通过 `p` 命令输出匹配内容 -e # 指定多个 `sed` 命令 -f # 从文件读取 `sed` 命令5.2 GNU
sed额外选项--version # 显示版本 --help # 显示帮助 --quiet, --silent # 与 `-n` 类似 --in-place[=SUFFIX] # 直接修改文件内容(可选备份) --regexp-extended, -r # 启用扩展正则5.3 BSD
sed额外选项(macOS 默认)-E # 启用扩展正则 -i # 直接修改文件内容(不支持 `--in-place`)
6. 正则表达式支持
sed使用 POSIX 基本正则表达式(BRE),GNUsed支持 扩展正则表达式(ERE):表达式 描述 *匹配前面字符 0 次或多次 .匹配任意单个字符 ^匹配行首 $匹配行尾 [abc]匹配 a、b或c[^abc]匹配非 a、b、c的字符\( \)进行分组(适用于 \1, \2){i,j}匹配 i 到 j 次 \b单词边界(GNU sed扩展)
7. sed 一行命令(Oneliners)
7.1 简单替换
sed "s/concieve/conceive/" file.txt # 仅替换每行的第一个匹配项 sed "s/concieve/conceive/g" file.txt # 替换所有匹配项7.2 多次替换
sed "s/concieve/conceive/g; s/recieve/receive/g" file.txt7.3 使用组匹配
echo "abccbd" | sed -r "s/a([bc]*)d/\1/g" # 结果:bccb7.4 处理日期格式
echo "03/11/2015 23:54:03" | sed -r "s/([0-9]+)\/([0-9]+)\/([0-9]+)/\3-\2-\1/g" # 结果:2015-11-03 23:54:037.5 处理引号
sed "s/\x22/'/g" file.txt # 将双引号 `"` 替换为单引号 `'`7.6 忽略大小写
echo "Hallo" | sed "s/hallo/hello/gi" # 结果:hello7.7 替换字母
echo "a2" | sed "s/[[:alpha:]]/z/g" # 结果:z2
8. sed 的局限性
- 不支持非贪婪匹配(
.*?)echo "abcbbc" | perl -pe "s/a.*?c/ac/" # 结果:acbbc - 不支持 Perl 风格的
\d, \D, \A, \Z - GNU
sed扩展特性不适用于所有sed版本
🎯 总结:
sed适用于行级别的文本转换,但复杂任务建议使用awk或perl。