sed 初级学习手册(修订版)
一、认识 sed
- 什么是 sed
- 全称:Stream Editor(流编辑器)
- 功能:非交互式命令行文本编辑器,用于对输入流进行文本转换和编辑
- 特点:批量处理、支持正则表达式、强大的文本处理能力
- 安装与验证
# 检查是否安装 sed --version # 安装命令 # Ubuntu/Debian: apt install sed # CentOS/RHEL: yum install sed # 基本测试 echo "Hello World" | sed 's/World/sed/'
- 基本概念
- 地址:指定要处理的行
- 命令:指定要执行的操作
- 脚本:命令的组合
- 模式空间:sed内部用于存储当前处理行的缓冲区
二、基本语法与选项
1. 基本用法格式
# 格式1:直接指定脚本
sed [选项] '脚本' 文件名...
# 格式2:从文件读取脚本
sed [选项] -f 脚本文件 文件名...
# 格式3:管道使用
命令 | sed [选项] '脚本'
# 格式4:标准输入
sed [选项] '脚本'
2. 常用选项详解(基于 sed –help)
选项 | 长选项 | 说明 |
---|---|---|
-n | --quiet, --silent | 抑制默认输出(只输出明确指定的内容) |
-e | --expression=脚本 | 添加脚本到命令中(可多次使用) |
-f | --file=脚本文件 | 从文件读取脚本 |
-i | --in-place[=后缀] | 原地编辑文件(提供后缀则备份原文件) |
-r | --regexp-extended | 使用扩展正则表达式(同-E) |
-E | --regexp-extended | 使用扩展正则表达式(推荐使用) |
-s | --separate | 将多个文件分别处理,而非作为连续流 |
-u | --unbuffered | 减少I/O缓冲,及时刷新输出 |
-z | --null-data | 使用NUL字符作为行分隔符 |
-b | --binary | 二进制模式(Windows兼容) |
--posix | 禁用所有GNU扩展,使用POSIX兼容模式 | |
--sandbox | 沙盒模式(禁用e/r/w命令) | |
--follow-symlinks | 原地编辑时跟随符号链接 | |
-c | --copy | 使用复制而非重命名方式处理文件(-i模式) |
-l | --line-length=N | 指定’l’命令的行包装长度 |
三、基本命令详解
1. 替换命令 (s)
# 基本替换语法:s/原字符串/新字符串/标志
sed 's/old/new/' file.txt # 只替换每行第一次出现
sed 's/old/new/g' file.txt # 全局替换(所有出现)
sed 's/old/new/i' file.txt # 忽略大小写替换
sed 's/old/new/p' file.txt # 替换并打印匹配行
sed 's/old/new/gp' file.txt # 全局替换并打印匹配行
sed 's/old/new/2' file.txt # 替换每行第2次出现
sed 's/old/new/gw output.txt' file.txt # 替换结果写入指定文件
# 使用不同分隔符(避免转义斜杠)
sed 's|/old/path|/new/path|' file.txt
sed 's_old_new_' file.txt
sed 's#http://#https://#' file.txt
2. 删除命令 (d)
# 删除指定行
sed '3d' file.txt # 删除第3行
sed '3,5d' file.txt # 删除第3到第5行
sed '3,$d' file.txt # 删除第3行到文件末尾
sed '1~2d' file.txt # 删除奇数行
sed '2~2d' file.txt # 删除偶数行
# 删除匹配模式的行
sed '/pattern/d' file.txt # 删除包含pattern的行
sed '/^$/d' file.txt # 删除空行
sed '/^[[:space:]]*$/d' file.txt # 删除空白行
sed '/^#/d' file.txt # 删除注释行
3. 打印命令 §
# 需要配合-n选项使用
sed -n '3p' file.txt # 打印第3行
sed -n '3,5p' file.txt # 打印第3到第5行
sed -n '/pattern/p' file.txt # 打印包含pattern的行
sed -n '1~2p' file.txt # 打印奇数行
sed -n '2~2p' file.txt # 打印偶数行
4. 插入命令 (i, a, c)
# 插入命令
sed '3i\新行内容' file.txt # 在第3行前插入
sed '/pattern/i\新行内容' file.txt # 在匹配行前插入
# 追加命令
sed '3a\新行内容' file.txt # 在第3行后追加
sed '/pattern/a\新行内容' file.txt # 在匹配行后追加
# 替换命令
sed '3c\新行内容' file.txt # 替换第3行
sed '/pattern/c\新行内容' file.txt # 替换匹配行
5. 其他常用命令
# 行号显示 (=)
sed '=' file.txt # 显示所有行号
sed '/pattern/=' file.txt # 显示匹配行的行号
# 列出行内容 (l)
sed -n 'l' file.txt # 显示所有行(转义特殊字符)
sed -n '/pattern/l' file.txt # 显示匹配行(转义特殊字符)
# 读取文件 (r)
sed '/pattern/r insert.txt' file.txt # 在匹配行后读入文件内容
# 写入文件 (w)
sed -n '/pattern/w output.txt' file.txt # 将匹配行写入文件
# 退出命令 (q)
sed '10q' file.txt # 处理10行后退出
sed '/pattern/q' file.txt # 匹配到pattern后退出
四、地址范围
1. 行号地址
# 单行地址
sed '5命令' file.txt # 处理第5行
# 行号范围
sed '5,10命令' file.txt # 处理第5到第10行
sed '5,$命令' file.txt # 处理第5行到文件末尾
sed '1,3!命令' file.txt # 处理除第1到第3行外的所有行
# 步进地址
sed '1~2命令' file.txt # 处理奇数行(1,3,5...)
sed '2~2命令' file.txt # 处理偶数行(2,4,6...)
2. 模式地址
# 单模式地址
sed '/pattern/命令' file.txt # 处理包含pattern的行
# 模式范围
sed '/start/,/end/命令' file.txt # 处理从包含start到包含end的行
sed '/pattern/,+3命令' file.txt # 处理包含pattern的行及其后3行
sed '/pattern/,$命令' file.txt # 处理包含pattern的行到文件末尾
# 模式与行号组合
sed '/pattern/,10命令' file.txt # 处理包含pattern的行到第10行
3. 地址否定
# 否定地址(处理不匹配的行)
sed '3!命令' file.txt # 处理除第3行外的所有行
sed '/pattern/!命令' file.txt # 处理不包含pattern的行
五、正则表达式详解
1. 基本正则表达式(默认)
# 字符匹配
sed 's/a/b/' file.txt # 匹配字符a
sed 's/./b/' file.txt # 匹配任意字符
sed 's/[abc]/X/' file.txt # 匹配a、b或c
sed 's/[^abc]/X/' file.txt # 匹配除a、b、c外的字符
# 重复匹配
sed 's/a*/X/' file.txt # 匹配0个或多个a
sed 's/a\+/X/' file.txt # 匹配1个或多个a(需要转义)
sed 's/a\{2,4\}/X/' file.txt # 匹配2到4个a(需要转义)
# 位置匹配
sed 's/^/X/' file.txt # 匹配行首
sed 's/$/X/' file.txt # 匹配行尾
sed 's/\<word\>/X/' file.txt # 匹配单词边界
2. 扩展正则表达式(-E选项)
# 使用-E选项启用扩展正则表达式
sed -E 's/a+/X/' file.txt # 匹配1个或多个a
sed -E 's/a{2,4}/X/' file.txt # 匹配2到4个a
sed -E 's/(group)+/X/' file.txt # 分组匹配
sed -E 's/pattern1|pattern2/X/' file.txt # OR操作
sed -E 's/(..)(..)/\2\1/' file.txt # 捕获组交换
3. 捕获组和引用
# 基本正则中的捕获组
sed 's/\(pattern\)/[\1]/' file.txt # 使用\1引用第一个捕获组
sed 's/\(first\)\(second\)/\2\1/' file.txt # 交换两个捕获组
# 扩展正则中的捕获组
sed -E 's/(pattern)/[\1]/' file.txt # 使用\1引用第一个捕获组
sed -E 's/(first)(second)/\2\1/' file.txt # 交换两个捕获组
六、实用示例
1. 文本替换
# 简单替换
sed 's/old/new/' file.txt
# 全局替换
sed 's/old/new/g' file.txt
# 忽略大小写替换
sed 's/old/new/gi' file.txt
# 使用捕获组
sed 's/\(pattern\)/[\1]/' file.txt
# 删除行首空白
sed 's/^[ \t]*//' file.txt
# 删除行尾空白
sed 's/[ \t]*$//' file.txt
# 替换多个空格为单个空格
sed 's/ */ /g' file.txt
# 删除所有空白字符
sed 's/[[:space:]]//g' file.txt
2. 文件处理
# 原地编辑文件
sed -i 's/old/new/g' file.txt
# 原地编辑并备份
sed -i.bak 's/old/new/g' file.txt
# 处理多个文件
sed 's/old/new/g' file1.txt file2.txt
# 从标准输入处理
cat file.txt | sed 's/old/new/g'
3. 复杂操作
# 多命令组合(使用分号)
sed 's/old/new/g; s/abc/xyz/g' file.txt
# 多命令组合(使用-e选项)
sed -e 's/old/new/g' -e 's/abc/xyz/g' file.txt
# 使用脚本文件
echo -e 's/old/new/g\ns/abc/xyz/g' > script.sed
sed -f script.sed file.txt
# 条件处理
sed '/pattern/{s/old/new/;p}' file.txt
# 多行处理
sed '/start/,/end/{s/old/new/g}' file.txt
4. 实际应用场景
# 配置文件处理
sed 's/#.*$//' file.conf | sed '/^$/d' # 删除注释和空行
# 日志处理
sed -n '/ERROR/p' application.log # 提取错误日志
sed '/DEBUG/d' application.log # 过滤调试日志
# CSV处理
sed 's/,/|/g' data.csv # 替换分隔符
# 格式转换
sed 's/\t/ /g' file.txt # Tab转空格
七、高级功能
1. 保持空间操作
# h - 将模式空间复制到保持空间
# H - 将模式空间追加到保持空间
# g - 将保持空间复制到模式空间
# G - 将保持空间追加到模式空间
# x - 交换模式空间和保持空间
# 示例:在文件末尾添加文件头
sed '1h; 1d; $G' file.txt
# 示例:反转文件行顺序
sed -n '1!G; h; $p' file.txt
2. 分支和测试命令
# b - 分支到标签(无标签则跳到脚本末尾)
# t - 测试(如果上次替换成功则分支)
# T - 测试(如果上次替换失败则分支)
# 示例:替换成功后退出
sed '/pattern/{s/old/new/; t; d}' file.txt
3. 原地编辑高级用法
# 创建带时间戳的备份
sed -i.$(date +%Y%m%d) 's/old/new/g' file.txt
# 处理符号链接
sed --follow-symlinks -i 's/old/new/g' symlink.txt
# 使用复制模式
sed -c -i 's/old/new/g' file.txt
八、常见问题解决
1. 特殊字符处理
# 处理包含斜杠的路径
sed 's|/old/path|/new/path|' file.txt
sed 's#/old/path#/new/path#' file.txt
# 处理特殊字符
sed 's/\*/STAR/g' file.txt # 替换星号
sed 's/\$/DOLLAR/g' file.txt # 替换美元符号
sed 's/\\/BACKSLASH/g' file.txt # 替换反斜杠
2. 性能优化
# 对大文件只处理前N行
sed '1000q; s/old/new/g' largefile.txt
# 使用地址范围限制处理范围
sed '100,200s/old/new/g' file.txt
# 避免不必要的全局替换
sed 's/old/new/' file.txt # 只替换第一次出现
3. 跨平台兼容性
# 使用POSIX模式
sed --posix 's/old/new/g' file.txt
# Windows兼容模式
sed -b 's/old/new/g' file.txt
# 使用扩展正则表达式的可移植性
sed -E 's/pattern1|pattern2/replacement/' file.txt # GNU/Linux
sed -r 's/pattern1|pattern2/replacement/' file.txt # 旧版本GNU sed
九、快速参考表
基本命令速查
s/old/new/ 替换(第一次出现)
s/old/new/g 全局替换
d 删除行
p 打印行(需-n选项)
i\text 在前插入
a\text 在后追加
c\text 替换行
= 显示行号
l 列出行内容
q 退出
地址范围速查
5 第5行
5,10 第5到第10行
5,$ 第5行到末尾
/pattern/ 包含pattern的行
/pattern/,/end/ 从pattern到end的行
1~2 奇数行
2~2 偶数行
常用正则表达式
^ 行首
$ 行尾
. 任意字符
* 前一字符0次或多次
\+ 前一字符1次或多次
\{n,m\} 前一字符n到m次
[abc] 字符类
[^abc] 非字符类
\(abc\) 捕获组(基本正则)
(abc) 捕获组(扩展正则)
实用组合示例
# 删除空行和注释行
sed '/^$/d; /^#/d' file.txt
# 提取文件头和尾各5行
sed -n '1,5p; $-4,$p' file.txt
# 给文件添加行号
sed '=' file.txt | sed 'N; s/\n/\t/'
# 合并连续的空行为单个空行
sed '/^$/N; /\n$/D' file.txt
# 在每个匹配行后添加标记
sed '/pattern/a\--- MATCH ---' file.txt
退出状态码
0 成功
1 无效命令或语法错误
2 无法访问文件或I/O错误
4 GNU sed内部错误
这个修订版手册基于sed --help
的完整输出,涵盖了所有主要选项和功能。掌握这些内容后,你可以高效地进行各种文本处理工作。