当前位置: 首页 > news >正文

sed 命令完整使用手册

📝 强大的流编辑器 - 文本处理神器


目录

  1. 简介
  2. 安装
  3. 基础语法
  4. 基础操作
  5. 地址与范围
  6. 命令详解
  7. 正则表达式
  8. 高级用法
  9. 实战示例
  10. 技巧与最佳实践
  11. sed vs 其他工具

一、简介

1.1 什么是 sed

sed(stream editor)是一个流编辑器,用于对文本进行过滤和转换。它是 Unix/Linux 系统中最古老且最强大的文本处理工具之一。

核心特点

  • 逐行处理文本
  • 支持正则表达式
  • 非交互式编辑
  • 可以原地修改文件
  • 支持脚本文件

1.2 工作原理

┌─────────────────────────────────────────────────────────────────────┐
│                    sed 工作流程                                     │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│    输入文件/标准输入                                                │
│         │                                                           │
│         ▼                                                           │
│    ┌─────────────┐                                                 │
│    │  读取一行   │                                                 │
│    └──────┬──────┘                                                 │
│           │                                                         │
│           ▼                                                         │
│    ┌─────────────┐    不匹配    ┌─────────────┐                    │
│    │  模式匹配   │ ──────────► │  输出原行   │                    │
│    └──────┬──────┘              └─────────────┘                    │
│           │ 匹配                                                    │
│           ▼                                                         │
│    ┌─────────────┐                                                 │
│    │  执行命令   │                                                 │
│    └──────┬──────┘                                                 │
│           │                                                         │
│           ▼                                                         │
│    ┌─────────────┐                                                 │
│    │  输出结果   │                                                 │
│    └─────────────┘                                                 │
│                                                                     │
│    重复直到文件结束                                                 │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

1.3 sed 模式空间与保持空间

┌─────────────────────────────────────────────────────────────────────┐
│                    sed 的两个缓冲区                                 │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  ┌──────────────────────────────────────────────────────────────┐  │
│  │ 模式空间 (Pattern Space)                                     │  │
│  │ ───────────────────────                                      │  │
│  │ • 当前处理的行                                               │  │
│  │ • 大多数命令在这里操作                                       │  │
│  │ • 每处理完一行,自动清空                                     │  │
│  └──────────────────────────────────────────────────────────────┘  │
│                                                                     │
│  ┌──────────────────────────────────────────────────────────────┐  │
│  │ 保持空间 (Hold Space)                                        │  │
│  │ ─────────────────────                                        │  │
│  │ • 临时存储区                                                 │  │
│  │ • 用于多行处理                                               │  │
│  │ • 需要手动管理                                               │  │
│  └──────────────────────────────────────────────────────────────┘  │
│                                                                     │
│  命令:h/H (复制/追加到保持空间), g/G (获取到模式空间)              │
│        x (交换)                                                    │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

二、安装

2.1 各平台安装

Linux

# Debian/Ubuntu
sudo apt update
sudo apt install sed# CentOS/RHEL
sudo yum install sed# Alpine
apk add sed# Arch Linux
sudo pacman -S sed

macOS

# macOS 自带 sed,但建议安装 GNU sed
brew install gsed# 创建别名
alias sed='gsed'

Windows

# Git Bash 自带 sed# 或通过 Chocolatey
choco install sed# 或使用 WSL
wsl sed

2.2 验证安装

sed --version
# 输出: sed (GNU sed) 4.8# 测试运行
echo "hello world" | sed 's/world/sed/'
# 输出: hello sed

2.3 BSD sed vs GNU sed

# BSD sed (macOS 默认)
# -i 需要指定备份后缀(可以是空字符串)
sed -i '' 's/old/new/' file.txt# GNU sed (Linux 默认)
# -i 不需要指定后缀
sed -i 's/old/new/' file.txt# 兼容写法
# 创建备份
sed -i.bak 's/old/new/' file.txt

三、基础语法

3.1 命令格式

sed [选项] '命令' [文件]# 或
sed [选项] -e '命令1' -e '命令2' [文件]# 或从脚本文件读取
sed [选项] -f 脚本文件 [文件]

3.2 常用选项

选项 说明 示例
-n 静默模式,不自动打印 sed -n 'p'
-e 添加脚本命令 sed -e 's/a/b/' -e 's/c/d/'
-f 从文件读取脚本 sed -f script.sed
-i 原地编辑文件 sed -i 's/old/new/' file
-i.bak 原地编辑并备份 sed -i.bak 's/old/new/' file
-r / -E 使用扩展正则表达式 sed -r 's/a+/b/'
-l 指定行长度 sed -l 80
-s 将文件视为独立流 sed -s '1p' *.txt
-u 无缓冲输出 sed -u 's/a/b/'
-z 使用 NUL 分隔行 sed -z 's/\n/ /g'

3.3 命令格式

[地址1[,地址2]]命令[参数]# 示例
sed 'p'          # 无地址,作用于所有行
sed '1p'         # 地址为 1,只作用于第 1 行
sed '1,5p'       # 地址为 1-5,作用于第 1-5 行
sed '/pattern/p' # 地址为匹配 pattern 的行

四、基础操作

4.1 替换命令 (s)

基本替换

# 替换每行第一个匹配
echo "hello world world" | sed 's/world/sed/'
# 输出: hello sed world# 全局替换
echo "hello world world" | sed 's/world/sed/g'
# 输出: hello sed sed# 替换第 N 个匹配
echo "aaa aaa aaa" | sed 's/aaa/bbb/2'
# 输出: aaa bbb aaa

替换标志

标志 说明 示例
g 全局替换 s/old/new/g
数字 替换第 N 个匹配 s/old/new/2
p 打印替换的行 s/old/new/p
w 文件 写入文件 s/old/new/w out.txt
i 忽略大小写 s/old/new/i
e 执行命令 s/.*/echo &/e
m 多行模式 s/^/>>/gm

分隔符

# 默认使用 /
sed 's/old/new/' file# 使用其他分隔符(推荐用于处理路径)
sed 's#/old#/new#' file
sed 's|/old|/new|' file
sed 's@/old@/new@' file
sed 's:/old:/new:' file# 使用 # 分隔符的示例
echo "/usr/local/bin" | sed 's#/usr#/opt#'
# 输出: /opt/local/bin

使用 & 和 \1

# & 代表匹配的整个文本
echo "hello" | sed 's/hello/[&]/'
# 输出: [hello]echo "hello world" | sed 's/\w\+/[&]/g'
# 输出: [hello] [world]# \1, \2 代表分组
echo "hello world" | sed 's/\(\w\+\) \(\w\+\)/[\1] [\2]/'
# 输出: [hello] [world]# 使用扩展正则(推荐)
echo "hello world" | sed -r 's/(\w+) (\w+)/[\1] [\2]/'
# 输出: [hello] [world]# 交换两个词
echo "hello world" | sed -r 's/(\w+) (\w+)/\2 \1/'
# 输出: world hello

4.2 删除命令 (d)

# 删除第 3 行
sed '3d' file.txt# 删除第 1-5 行
sed '1,5d' file.txt# 删除最后一行
sed '$d' file.txt# 删除空行
sed '/^$/d' file.txt# 删除匹配行
sed '/pattern/d' file.txt# 删除不匹配的行
sed '/pattern/!d' file.txt# 删除注释行(以 # 开头)
sed '/^#/d' file.txt# 删除所有行(仅显示)
seq 5 | sed 'd'
# 无输出# 删除从匹配行到末尾
sed '/pattern/,$d' file.txt

4.3 打印命令 (p)

# 打印第 3 行(会打印两次)
sed '3p' file.txt# 只打印第 3 行
sed -n '3p' file.txt# 打印第 1-5 行
sed -n '1,5p' file.txt# 打印最后一行
sed -n '$p' file.txt# 打印匹配行
sed -n '/pattern/p' file.txt# 打印行号
sed '=' file.txt# 打印行号和内容
sed '=' file.txt | sed 'N;s/\n/ /'# 打印奇数行
sed -n '1~2p' file.txt# 打印偶数行
sed -n '2~2p' file.txt# 打印从第 N 行开始的所有行
sed -n '5,$p' file.txt

4.4 插入与追加 (i, a)

# 在第 2 行前插入
sed '2i\INSERTED LINE' file.txt# 在第 2 行后追加
sed '2a\APPENDED LINE' file.txt# 在文件开头插入
sed '1i\HEADER' file.txt# 在文件末尾追加
sed '$a\FOOTER' file.txt# 在匹配行前插入
sed '/pattern/i\BEFORE' file.txt# 在匹配行后追加
sed '/pattern/a\AFTER' file.txt# 在每行前插入
sed 'i\> ' file.txt# 在每行后追加
sed 'a\---' file.txt# 插入多行
sed '2i\
LINE 1\
LINE 2\
LINE 3' file.txt

4.5 修改命令 (c)

# 替换第 2 行
sed '2c\REPLACED LINE' file.txt# 替换第 1-3 行
sed '1,3c\REPLACED MULTIPLE LINES' file.txt# 替换匹配行
sed '/pattern/c\REPLACED' file.txt# 替换空行
sed '/^$/c\EMPTY' file.txt

4.6 原地编辑 (-i)

# 直接修改文件(危险操作)
sed -i 's/old/new/' file.txt# 修改前备份
sed -i.bak 's/old/new/' file.txt# 批量修改
sed -i 's/old/new/' *.txt# 递归修改
find . -name "*.txt" -exec sed -i 's/old/new/' {} +# macOS 兼容写法
sed -i '' 's/old/new/' file.txt

五、地址与范围

5.1 行号地址

# 第 N 行
sed '3p' file.txt# 第 N 到 M 行
sed '3,5p' file.txt# 最后一行
sed '$p' file.txt# 从第 N 行到末尾
sed '3,$p' file.txt# 第 N 行之后的 M 行
sed '3,+2p' file.txt# 每 N 行
sed '1~3p' file.txt  # 第 1, 4, 7, 10... 行

5.2 正则地址

# 匹配 pattern 的行
sed '/pattern/p' file.txt# 从匹配 start 到匹配 end
sed '/start/,/end/p' file.txt# 从第 N 行到匹配 pattern
sed '3,/pattern/p' file.txt# 从匹配 pattern 到末尾
sed '/pattern/,$p' file.txt# 匹配多个模式
sed '/pattern1/p; /pattern2/p' file.txt

5.3 地址取反 (!)

# 删除不匹配的行
sed '/pattern/!d' file.txt# 修改不匹配的行
sed '/pattern/!s/^/# /' file.txt# 打印不匹配的行
sed -n '/pattern/!p' file.txt# 删除除第 3-5 行外的所有行
sed '3,5!d' file.txt

5.4 地址组合

# 多个地址范围
sed -e '1,5s/old/new/' -e '10,15s/foo/bar/' file.txt# 嵌套地址
sed '/start/,/end/{/pattern/p}' file.txt# 条件执行多个命令
sed '/pattern/{s/old/new/; s/foo/bar/}' file.txt

六、命令详解

6.1 替换命令 (s///)

# 语法
s/模式/替换/[标志]# 基本替换
sed 's/hello/world/' file.txt# 使用不同的分隔符
sed 's|/usr/local|/opt|' file.txt
sed 's#/usr/local#/opt#' file.txt# 忽略大小写
sed 's/hello/WORLD/i' file.txt# 多次替换
sed 's/a/A/g; s/b/B/g' file.txt# 条件替换
sed '/pattern/s/old/new/' file.txt# 分组替换
sed -r 's/([a-z]+) ([0-9]+)/\2 \1/' file.txt# 大小写转换
# \u 首字母大写
echo "hello" | sed 's/\w\+/\u&/'
# 输出: Hello# \U 全部大写
echo "hello" | sed 's/\w\+/\U&/'
# 输出: HELLO# \l 首字母小写
echo "HELLO" | sed 's/\w\+/\l&/'
# 输出: hELLO# \L 全部小写
echo "HELLO" | sed 's/\w\+/\L&/'
# 输出: hello# \E 结束大小写转换
echo "hello WORLD" | sed 's/\w\+/\u&\E/g'
# 输出: Hello World

6.2 删除命令 (d)

# 删除指定行
sed '5d' file.txt# 删除范围行
sed '3,7d' file.txt# 删除空行
sed '/^$/d' file.txt# 删除空白行(包含空格)
sed '/^[[:space:]]*$/d' file.txt# 删除注释行
sed '/^#/d' file.txt# 删除匹配行
sed '/error/d' file.txt# 保留匹配行(删除不匹配的)
sed '/success/!d' file.txt# 删除连续空行(只保留一个)
sed '/./,/^$/!d' file.txt# 删除第 N 行到匹配行
sed '3,/pattern/d' file.txt

6.3 打印命令 (p)

# 打印行
sed -n '3p' file.txt# 打印范围
sed -n '3,5p' file.txt# 打印匹配行
sed -n '/pattern/p' file.txt# 打印并显示行号
sed -n '/pattern/{=;p}' file.txt# 打印前 N 行
sed -n '1,5p' file.txt# 打印最后 N 行
sed -n '$p' file.txt# 打印奇偶行
sed -n '1~2p' file.txt  # 奇数行
sed -n '2~2p' file.txt  # 偶数行

6.4 插入/追加 (i/a)

# 插入 (i) - 在行前
sed '3i\INSERTED' file.txt# 追加 (a) - 在行后
sed '3a\APPENDED' file.txt# 在匹配行前后添加
sed '/pattern/i\BEFORE' file.txt
sed '/pattern/a\AFTER' file.txt# 添加多行
sed '3a\
LINE 1\
LINE 2' file.txt# 在行首添加
sed 's/^/PREFIX /' file.txt# 在行尾添加
sed 's/$/ SUFFIX/' file.txt

6.5 修改命令 (c)

# 替换整行
sed '3c\NEW LINE' file.txt# 替换范围
sed '3,5c\REPLACED' file.txt# 替换匹配行
sed '/pattern/c\REPLACED' file.txt

6.6 读写命令 (r/w)

# 读取文件并插入
sed '/pattern/r insert.txt' file.txt# 在指定行后插入文件
sed '3r insert.txt' file.txt# 写入到文件
sed -n '/pattern/w output.txt' file.txt# 写入指定行
sed -n '3,5w output.txt' file.txt# 分割文件
sed -n '/pattern1/w file1.txt; /pattern2/w file2.txt' file.txt

6.7 多行命令 (N/D/P)

# N - 读取下一行到模式空间
sed 'N' file.txt  # 合并相邻两行# 合并所有行
sed ':a;N;$!ba;s/\n/ /g' file.txt# D - 删除模式空间第一行
sed 'N;D' file.txt# P - 打印模式空间第一行
sed -n 'N;P' file.txt# 处理跨行匹配
sed 'N;s/pattern1\npattern2/replacement/' file.txt# 删除空行并合并
sed '/^$/N;/^\n$/D' file.txt

6.8 保持空间命令 (h/H/g/G/x)

# h - 复制模式空间到保持空间
# H - 追加模式空间到保持空间
# g - 复制保持空间到模式空间
# G - 追加保持空间到模式空间
# x - 交换模式空间和保持空间# 反转文件行
sed -n '1!G;h;$p' file.txt# 反转文件(更简洁)
tac file.txt  # 或 sed '1!G;h;$!d' file.txt# 合并相邻行
sed 'N;s/\n/ /' file.txt# 交换行(交换第 2 和第 3 行)
sed '2{h;d};3{G}' file.txt# 复制行
sed '/pattern/{h};/pattern2/{G}' file.txt# 累积匹配行
sed '/pattern/H;$!d;g' file.txt

6.9 分支与测试 (b/t/😃

# :label - 定义标签
# b label - 跳转到标签
# t label - 如果替换成功则跳转
# T label - 如果替换失败则跳转# 删除所有行的前导空格
sed ':a;s/^\( *\)\( *\)/\1/;ta' file.txt# 循环替换直到没有变化
sed ':a;s/  */ /g;ta' file.txt# 条件跳转
sed '/pattern/b end; s/old/new/; :end' file.txt# 删除嵌套括号内容
sed ':a;s/([^()]*)//g;ta' file.txt# 计算行数
sed -n '$=' file.txt

6.10 其他命令

# = - 打印行号
sed '=' file.txt# l - 打印不可见字符
sed -n 'l' file.txt# q - 退出
sed '5q' file.txt  # 只处理前 5 行# Q - 静默退出
sed '/pattern/Q' file.txt# # - 注释
sed '# This is a comment' file.txt# {} - 命令分组
sed '/pattern/{s/old/new/;p}' file.txt# y - 字符转换(类似 tr)
sed 'y/abc/ABC/' file.txt# v - 版本检查
sed --version

七、正则表达式

7.1 基本正则 (BRE)

# 基本字符
.      # 任意单个字符
*      # 前一个字符出现 0 次或多次
^      # 行首
$      # 行尾
[list] # 字符列表
[^]    # 不在列表中的字符
\n     # 换行符
\      # 转义字符# 示例
sed 's/a.c/XYZ/' file.txt      # abc, a1c, a_c 等都会被匹配
sed 's/ab*c/XYZ/' file.txt     # ac, abc, abbc 等都会被匹配
sed 's/^start/START/' file.txt # 只匹配行首的 start
sed 's/end$/END/' file.txt     # 只匹配行尾的 end
sed 's/[abc]/X/' file.txt      # 匹配 a, b, c 中的任意一个
sed 's/[^abc]/X/' file.txt     # 匹配不是 a, b, c 的字符

7.2 扩展正则 (ERE)

# 使用 -r 或 -E 选项
sed -r 's/pattern/replacement/' file.txt# 扩展字符
+      # 前一个字符出现 1 次或多次
?      # 前一个字符出现 0 次或 1 次
{n}    # 前一个字符出现 n 次
{n,}   # 前一个字符出现至少 n 次
{n,m}  # 前一个字符出现 n 到 m 次
|      # 或
()     # 分组# 示例
sed -r 's/ab+c/XYZ/' file.txt     # abc, abbc, abbbc 等
sed -r 's/ab?c/XYZ/' file.txt     # ac, abc
sed -r 's/a{3}/AAA/' file.txt     # aaa 被替换为 AAA
sed -r 's/a{2,4}/AA/' file.txt    # aa, aaa, aaaa 被替换为 AA
sed -r 's/cat|dog/pet/' file.txt  # cat 或 dog 被替换为 pet
sed -r 's/(ab)+/X/' file.txt      # ab, abab, ababab 等

7.3 字符类

# POSIX 字符类
[:alnum:]   # 字母和数字
[:alpha:]   # 字母
[:blank:]   # 空格和制表符
[:cntrl:]   # 控制字符
[:digit:]   # 数字
[:graph:]   # 可打印字符(不包括空格)
[:lower:]   # 小写字母
[:print:]   # 可打印字符
[:punct:]   # 标点符号
[:space:]   # 空白字符
[:upper:]   # 大写字母
[:xdigit:]  # 十六进制数字# 示例
sed 's/[[:digit:]]/X/g' file.txt      # 替换所有数字
sed 's/[[:space:]]+/,/g' file.txt     # 替换连续空格为逗号
sed 's/[[:upper:]]/\L&/g' file.txt    # 转换为小写
sed 's/[[:punct:]]//g' file.txt       # 删除标点符号

7.4 正则示例

# 匹配邮箱
sed -r 's/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/EMAIL/g' file.txt# 匹配 URL
sed -r 's|https?://[^[:space:]]+|URL|g' file.txt# 匹配 IP 地址
sed -r 's/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/IP/g' file.txt# 匹配日期 (YYYY-MM-DD)
sed -r 's/[0-9]{4}-[0-9]{2}-[0-9]{2}/DATE/g' file.txt# 匹配电话号码
sed -r 's/[0-9]{3}-[0-9]{4}-[0-9]{4}/PHONE/g' file.txt# 匹配 HTML 标签
sed -r 's/<[^>]+>//g' file.html# 匹配重复单词
sed -r 's/\b(\w+)\s+\1\b/\1/g' file.txt# 删除前后空格
sed 's/^[[:space:]]*//;s/[[:space:]]*$//' file.txt

八、高级用法

8.1 多命令执行

# 使用 -e 选项
sed -e 's/a/A/' -e 's/b/B/' file.txt# 使用分号
sed 's/a/A/; s/b/B/' file.txt# 使用 { } 分组
sed '/pattern/{s/a/A/;s/b/B/}' file.txt# 使用换行(在脚本中更清晰)
sed '
s/a/A/
s/b/B/
s/c/C/
' file.txt

8.2 脚本文件

# 创建 sed 脚本文件 script.sed
#!/usr/bin/sed -f# 删除空行
/^$/d# 删除注释
/^#/d# 替换
s/old/new/g# 使用脚本
sed -f script.sed file.txt# 直接执行脚本
chmod +x script.sed
./script.sed file.txt

8.3 模式空间与保持空间

# 模式空间 - 当前处理的行
# 保持空间 - 临时存储# h - 复制模式空间到保持空间(覆盖)
# H - 追加模式空间到保持空间
# g - 复制保持空间到模式空间(覆盖)
# G - 追加保持空间到模式空间
# x - 交换两个空间# 示例:反转行顺序
seq 5 | sed -n '1!G;h;$p'
# 输出:
# 5
# 4
# 3
# 2
# 1# 示例:合并每两行
sed 'N;s/\n/ /' file.txt# 示例:复制匹配行到文件末尾
sed -n '/pattern/H;$p' file.txt# 示例:累积内容
sed '/pattern/!d;H;$!d;g' file.txt

8.4 分支与循环

# :label - 定义标签
# b label - 无条件跳转
# t label - 替换成功则跳转
# T label - 替换失败则跳转# 示例:循环删除多余的空格
sed ':a;s/  / /;ta' file.txt# 示例:循环添加前缀
echo "abc" | sed ':a;s/^/>>/;ta'
# 无限循环!不要这样做# 示例:有条件的循环
sed ':a;s/abc/X/;ta' file.txt  # 替换所有的 abc 为 X# 示例:跳过某些行
sed '/pattern/b skip; s/old/new/; :skip' file.txt# 示例:删除嵌套括号
sed ':a;s/([^()]*)//g;ta' file.txt

8.5 多行处理

# N - 读取下一行到模式空间
# D - 删除模式空间第一行
# P - 打印模式空间第一行# 示例:合并相邻行
sed 'N;s/\n/ /' file.txt# 示例:合并所有行
sed ':a;N;$!ba;s/\n/ /g' file.txt# 示例:删除空行(保留一个)
sed '/^$/N;/^\n$/D' file.txt# 示例:跨行替换
sed 'N;s/pattern1\npattern2/replacement/' file.txt# 示例:格式化段落
sed '/./{H;$!d};x;s/\n\n*/\n\n/g' file.txt# 示例:删除 HTML 标签(多行)
sed ':a;N;$!ba;s/<[^>]*>//g' file.html

8.6 条件执行

# {} 分组命令
sed '/pattern/{s/a/A/;s/b/B/;p}' file.txt# 多条件
sed '/pattern1/{s/a/A//pattern2/d
}' file.txt# 嵌套条件
sed '/start/,/end/{/pattern1/s/old/new//pattern2/d
}' file.txt# 使用 ! 取反
sed '/pattern/!s/old/new/' file.txt# 条件退出
sed '/pattern/q' file.txt# 条件写入
sed -n '/pattern/w output.txt' file.txt

8.7 高级替换技巧

# 大小写转换
# \u - 首字母大写
# \U - 全部大写
# \l - 首字母小写
# \L - 全部小写
# \E - 结束转换echo "hello world" | sed 's/\w\+/\u&/g'
# 输出: Hello Worldecho "hello world" | sed 's/.*/\U&/'
# 输出: HELLO WORLD# 驼峰转换
echo "hello_world_test" | sed -r 's/(_|^)([a-z])/\U\2/g'
# 输出: HelloWorldTest# 蛇形转换
echo "HelloWorldTest" | sed -r 's/([A-Z])/_\L\1/g;s/^_//'
# 输出: hello_world_test# 每行添加行号
sed '=' file.txt | sed 'N;s/\n/\t/'# 添加序号
sed = file.txt | sed 'N;s/^/   /;s/\n/\t/'

九、实战示例

9.1 文本清理

删除空白行

# 删除完全空白的行
sed '/^$/d' file.txt# 删除只含空格/制表符的行
sed '/^[[:space:]]*$/d' file.txt# 删除连续空行(保留一个)
sed '/./,/^$/!d' file.txt# 删除开头的空行
sed '/./,$!d' file.txt# 删除结尾的空行
sed -e :a -e '/^\n*$/{$d;N;};$!ba' file.txt

删除注释

# 删除 # 开头的注释
sed '/^#/d' file.txt# 删除行内注释(保留内容)
sed 's/#.*//' file.txt# 删除 // 注释(C 风格)
sed 's|//.*||' file.txt# 删除 /* */ 注释(简单)
sed 's|/\*.*\*/||' file.txt# 删除多行注释
sed ':a;s|/\*[^*]*\*\+\([^/*][^*]*\*\+\)*/||;ta' file.txt

去除空格

# 删除行首空格
sed 's/^[[:space:]]*//' file.txt# 删除行尾空格
sed 's/[[:space:]]*$//' file.txt# 删除首尾空格
sed 's/^[[:space:]]*//;s/[[:space:]]*$//' file.txt# 压缩多个空格为一个
sed 's/[[:space:]]\+/ /g' file.txt# 删除所有空格
sed 's/[[:space:]]//g' file.txt

9.2 文本转换

大小写转换

# 首字母大写
sed 's/\b\(.\)/\u\1/' file.txt# 每个单词首字母大写
sed -r 's/\b([a-z])/\u\1/g' file.txt# 全部大写
sed 's/.*/\U&/' file.txt# 全部小写
sed 's/.*/\L&/' file.txt# 句首大写
sed 's/^\(.\)/\u\1/' file.txt

格式转换

# CSV 转表格
sed 's/,/\t/g' file.csv# 制表符转空格
sed 's/\t/  /g' file.txt# 空格转制表符
sed 's/  /\t/g' file.txt# 添加引号
sed 's/[^,]*/"&"/g' file.csv# 转换为 HTML 段落
sed 's/.*$/<p>&<\/p>/' file.txt# 添加 HTML 转义
sed 's/&/\&amp;/g;s/</\&lt;/g;s/>/\&gt;/g' file.txt

编码转换

# URL 编码(简单版)
sed 's/%/%25/g;s/ /%20/g;s/\//%2F/g' file.txt# HTML 实体解码(简单版)
sed 's/&lt;/</g;s/&gt;/>/g;s/&amp;/\&/g' file.txt# Base64 编码(需要配合)
sed 's/.*/echo & | base64/e' file.txt

9.3 日志处理

Apache 日志

# 提取 IP 地址
sed -n 's/^\([0-9.]*\).*/\1/p' access.log# 提取特定状态码
sed -n '/" 404 /p' access.log# 提取特定日期的日志
sed -n '/\[02\/Jan\/2024/p' access.log# 统计 URL
sed -n 's/.*"\([A-Z]*\) \([^ ]*\) .*/\2/p' access.log | sort | uniq -c

Nginx 日志

# 提取响应时间
sed -n 's/.* \([0-9.]*\)$/\1/p' access.log# 找出慢请求(>1s)
sed -n '/ [1-9][0-9]*\.[0-9]*$/p' access.log# 提取 User-Agent
sed -n 's/.*"\([^"]*\)"$/\1/p' access.log

应用日志

# 提取错误日志
sed -n '/ERROR/p' app.log# 提取特定时间范围
sed -n '/2024-01-01 10:00/,/2024-01-01 11:00/p' app.log# 提取异常堆栈(多行)
sed -n '/Exception/,/^[[:space:]]*$/p' app.log# 统计日志级别
sed -n 's/.*\(ERROR\|WARN\|INFO\|DEBUG\).*/\1/p' app.log | sort | uniq -c

9.4 配置文件处理

修改配置

# 修改配置值
sed -i 's/max_connections=.*/max_connections=100/' config.ini# 注释掉配置
sed -i 's/^option=/#option=/' config.ini# 取消注释
sed -i 's/^#option=/option=/' config.ini# 添加配置(如果不存在)
grep -q "new_option" config.ini || sed -i '$a new_option=value' config.ini# 替换端口
sed -i 's/port=.*/port=8080/' config.ini

INI 文件

# 提取节
sed -n '/\[section\]/,/^\[/p' config.ini# 提取键值
sed -n 's/^key=\(.*\)/\1/p' config.ini# 添加新节
sed -i '/^\[/a [new_section]' config.ini# 删除节
sed -i '/\[section\]/,/^\[/{/^\[/!d}' config.ini

JSON 文件(简单处理)

# 修改 JSON 值(简单版)
sed -i 's/"key":.*/"key": "new_value",/' config.json# 提取值(简单版)
sed -n 's/.*"key": *"\([^"]*\)".*/\1/p' config.json# 格式化 JSON(需要配合)
# 注意:复杂 JSON 处理建议使用 jq

9.5 代码处理

批量重命名变量

# 重命名变量
sed -i 's/oldName/newName/g' *.js# 重命名函数
sed -i 's/function oldFunc/function newFunc/g' *.js# 重命名类
sed -i 's/class OldClass/class NewClass/g' *.php

代码清理

# 删除调试语句
sed -i '/console\.log/d' *.js
sed -i '/print(/d' *.py
sed -i '/System\.out\.println/d' *.java# 删除 TODO 注释
sed -i '/\/\/ TODO/d' *.js# 删除空行
sed -i '/^$/d' *.py

代码格式化

# 删除行尾空格
sed -i 's/[[:space:]]*$//' *.py# 统一缩进(空格转制表符)
sed -i 's/    /\t/g' *.py# 添加分号(如果缺失)
sed -i 's/\([^;]\)$/\1;/' *.js

9.6 数据提取

提取字段

# 提取第一列
sed 's/^\([^,]*\),.*/\1/' file.csv# 提取第 N 列(以逗号分隔)
sed 's/^[^,]*,\([^,]*\),.*/\1/' file.csv  # 第 2 列# 提取最后一列
sed 's/.*,\([^,]*\)$/\1/' file.csv# 提取特定格式
sed -n 's/.*id=\([0-9]*\).*/\1/p' file.txt

提取匹配内容

# 提取邮箱
sed -n 's/.*\([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]\{2,\}\).*/\1/p' file.txt# 提取 URL
sed -n 's/.*\(https\?:\/\/[^ ]*\).*/\1/p' file.txt# 提取 IP 地址
sed -n 's/.*\([0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\).*/\1/p' file.txt# 提取日期
sed -n 's/.*\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\).*/\1/p' file.txt

9.7 文本分析

统计

# 统计行数
sed -n '$=' file.txt# 统计单词数
sed 's/[^[:space:]]//g' file.txt | wc -c# 统计字符数
sed 's/\n//g' file.txt | wc -c# 统计某个词出现次数
sed -n 's/word/word/gp' file.txt | wc -l

查找

# 查找包含 pattern 的行
sed -n '/pattern/p' file.txt# 查找不包含 pattern 的行
sed -n '/pattern/!p' file.txt# 查找并显示行号
sed -n '/pattern/{=;p}' file.txt# 查找上下文
sed -n '/pattern/{N;P}' file.txt  # 下一行

十、技巧与最佳实践

10.1 调试技巧

# 显示详细信息
sed --version# 测试命令(不修改文件)
sed 's/old/new/' file.txt# 使用 -n 调试
sed -n 's/old/new/p' file.txt# 打印模式空间
sed -n 'l' file.txt# 分步执行
sed 's/a/A/' file.txt | sed 's/b/B/'# 使用 echo 测试
echo "test string" | sed 's/test/TEST/'

10.2 性能优化

# 使用地址范围限制
sed '1,100s/old/new/' large.txt  # 只处理前 100 行# 合并多个命令
sed 's/a/A/; s/b/B/; s/c/C/' file.txt  # 优于三次调用# 提前退出
sed '/pattern/q' file.txt  # 找到后立即退出# 使用 -s 处理多个小文件
sed -s '1p' *.txt# 避免不必要的替换
sed '/pattern/s/old/new/' file.txt  # 只在匹配行替换

10.3 安全实践

# 始终备份
sed -i.bak 's/old/new/' file.txt# 先测试
sed 's/old/new/' file.txt > /dev/null && sed -i 's/old/new/' file.txt# 使用版本控制
git commit -am "Before sed changes"
sed -i 's/old/new/' *.txt
git diff# 限制范围
sed '1,10s/old/new/' file.txt  # 只处理前 10 行# 检查结果
sed -i 's/old/new/' file.txt
grep "new" file.txt | head

10.4 常用脚本

# 删除 CRLF(Windows 换行)
sed 's/\r$//' file.txt# 添加 CRLF
sed 's/$/\r/' file.txt# 删除 BOM
sed '1s/^\xEF\xBB\xBF//' file.txt# 删除 ANSI 颜色代码
sed 's/\x1b\[[0-9;]*m//g' file.txt# 去除 HTML 标签
sed 's/<[^>]*>//g' file.html# 合并多行为一行
sed ':a;N;$!ba;s/\n/ /g' file.txt# 分割每行到多行
sed 's/.\{80\}/&\n/g' file.txt# 添加行号
sed = file.txt | sed 'N;s/\n/\t/'# 反转行
sed -n '1!G;h;$p' file.txt

10.5 常见陷阱

陷阱 1:忘记引号

# 错误
sed s/old/new/ file.txt  # 特殊字符会出问题# 正确
sed 's/old/new/' file.txt

陷阱 2:分隔符冲突

# 错误(路径中的 / 会冲突)
sed 's//usr/local//opt/' file.txt# 正确(使用其他分隔符)
sed 's|/usr/local|/opt|' file.txt

陷阱 3:贪婪匹配

# 贪婪匹配(匹配到最后一个)
echo "<a><b>text</b></a>" | sed 's/<.*>//'
# 输出: text</b></a>(错误)# 非贪婪匹配(使用 [^>])
echo "<a><b>text</b></a>" | sed 's/<[^>]*>//g'
# 输出: text(正确)

陷阱 4:macOS sed

# Linux
sed -i 's/old/new/' file.txt# macOS(需要指定备份后缀)
sed -i '' 's/old/new/' file.txt# 兼容写法(创建备份)
sed -i.bak 's/old/new/' file.txt

陷阱 5:多行处理

# 错误:sed 默认不处理跨行
sed 's/line1\nline2/replaced/' file.txt  # 不会工作# 正确:使用 N 读取多行
sed 'N;s/line1\nline2/replaced/' file.txt

十一、sed vs 其他工具

11.1 sed vs awk

# sed:简单的文本替换
sed 's/old/new/' file.txt# awk:复杂的数据处理
awk '{gsub(/old/, "new"); print}' file.txt# sed 适合:
# - 简单替换
# - 删除行
# - 行编辑# awk 适合:
# - 按列处理
# - 复杂计算
# - 格式化输出

11.2 sed vs grep

# grep:查找匹配行
grep "pattern" file.txt# sed:查找并修改
sed '/pattern/s/old/new/' file.txt# grep 适合:查找
# sed 适合:替换和编辑

11.3 sed vs tr

# tr:字符转换
tr 'a-z' 'A-Z' < file.txt# sed:更灵活的转换
sed 's/[a-z]/\U&/g' file.txt# tr 适合:单字符转换
# sed 适合:模式匹配和替换

11.4 sed vs perl

# sed:简单替换
sed 's/old/new/g' file.txt# perl:更强大的正则
perl -pe 's/old/new/g' file.txt# sed 适合:简单任务
# perl 适合:复杂正则和处理

11.5 选择建议

任务 推荐工具
简单替换 sed
删除/插入行 sed
按列处理 awk
查找匹配 grep
JSON 处理 jq
复杂正则 perl
交互编辑 vim

附录

A. 命令速查表

地址

地址 说明 示例
N 第 N 行 3p
N,M 第 N 到 M 行 3,5p
$ 最后一行 $p
/pattern/ 匹配 pattern 的行 /error/p
/p1/,/p2/ 从匹配 p1 到 p2 /start/,/end/p
N~M 从 N 开始每 M 行 1~2p
! 取反 /pattern/!d

命令

命令 说明 示例
s 替换 s/old/new/
d 删除 3d
p 打印 -n '3p'
i 行前插入 3i\text
a 行后追加 3a\text
c 替换整行 3c\text
r 读取文件 3r file
w 写入文件 3w file
y 字符转换 y/abc/ABC/
= 打印行号 3=
q 退出 5q
N 读取下一行 N
D 删除首行 D
P 打印首行 P
h 复制到保持空间 h
g 从保持空间获取 g
x 交换 x
:label 定义标签 :a
b label 跳转 ba
t label 成功跳转 ta

替换标志

标志 说明 示例
g 全局替换 s/a/b/g
N 替换第 N 个 s/a/b/2
p 打印替换的行 s/a/b/p
w file 写入文件 s/a/b/w out
i 忽略大小写 s/a/b/i
e 执行命令 s/.*/echo &/e

正则

元字符 说明 示例
. 任意字符 a.c
* 0 次或多次 ab*c
+ 1 次或多次 ab+c
? 0 次或 1 次 ab?c
^ 行首 ^start
$ 行尾 end$
[abc] 字符集 [a-z]
[^abc] 不在字符集 [^0-9]
\{n\} 出现 n 次 a\{3\}
\{n,m\} 出现 n-m 次 a\{2,4\}
\(...\) 分组 \(ab\)*
\1 引用分组 s/\(a\)/\1\1/
& 匹配文本 s/abc/[&]/

B. 常用脚本

文本清理

# 删除空行
sed '/^$/d' file.txt# 删除行首行尾空格
sed 's/^[[:space:]]*//;s/[[:space:]]*$//' file.txt# 压缩多个空格
sed 's/[[:space:]]\+/ /g' file.txt# 删除 CRLF
sed 's/\r$//' file.txt

格式转换

# 添加行号
sed = file.txt | sed 'N;s/\n/\t/'# 添加前缀
sed 's/^/PREFIX /' file.txt# 添加后缀
sed 's/$/ SUFFIX/' file.txt# 反转行
sed -n '1!G;h;$p' file.txt

数据提取

# 提取邮箱
sed -n 's/.*\([a-zA-Z0-9._%+-]\+@[a-zA-Z0-9.-]\+\.[a-zA-Z]\{2,\}\).*/\1/p' file.txt# 提取 URL
sed -n 's/.*\(https\?:\/\/[^ ]*\).*/\1/p' file.txt# 提取 IP
sed -n 's/.*\([0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\).*/\1/p' file.txt

C. 在线资源

  • 官方文档: https://www.gnu.org/software/sed/manual/
  • sed 教程: https://www.grymoire.com/Unix/Sed.html
  • sed 单行脚本: https://sed.sourceforge.io/sed1line.txt
  • sed 示例: https://www.gnu.org/software/sed/manual/html_node/Examples.html

文档版本:1.0
最后更新:2026-04-08
作者:小沃

http://www.jsqmd.com/news/624497/

相关文章:

  • 【实战】海康摄像头RTSP流媒体连接中的特殊字符陷阱:从401错误到URL编码的终极解决
  • 泛微Ecology异构集成避坑指南:许可证(AppID)管理与安全配置的那些事儿
  • 5分钟快速上手!跨平台资源下载神器res-downloader完整指南
  • windows安装mysql8.0.33
  • 多账号矩阵运营的技术难点与工程化落地实践
  • PostgreSQL权限体系深度解析:从表空间到角色的实战指南
  • MATLAB图像分割实战:从基础阈值到分水岭算法的进阶指南
  • 双缓冲技术在操作系统开发中的应用
  • Вот перевод предоставленного текста на русский язык -pay
  • 自动螺丝供料技术:自动送钉系统的核心功能解析
  • 长春黄金回收鉴定哪家好
  • CentOS 7 等保测评踩坑记:手把手教你用脚本升级OpenSSH到9.6p1(附完整回滚方案)
  • hot 100 73. 矩阵置零
  • 认证技术中的考试大纲认证流程与续证要求
  • Cursor与Figma的MCP桥梁:从零搭建智能设计协作环境
  • Python资源合集
  • 2026年上海家装行业优质品牌评定报告 - 速递信息
  • 英语阅读_Art is a part of human culture
  • MediaCodec 编解码基础:Buffer 队列、状态机与零拷贝的艺术
  • Cosmos-Reason1-7B实际效果:对机器人抓取动作进行接触力与稳定性预判
  • 如何高效使用智能激活工具:KMS_VL_ALL_AIO完整实践指南
  • YOLOv10新手必看:镜像内Markdown文档,帮你秒懂所有操作
  • 惠普暗影精灵硬件控制新选择:OmenSuperHub技术解析与实践指南
  • Open GApps包怎么选?从Platform到Variant,一次讲清安卓11/12 GMS安装包下载门道
  • Windows 10/11 鼠标指针美化终极指南:免费获取macOS风格指针
  • 如何用Python脚本实现京东茅台自动化抢购:jd_maotai实战指南
  • mPLUG-Owl3-2B图文交互工具入门必看:上传→提问→解析三步闭环
  • Tableau 中实现优雅曲线:平滑折线图的进阶技巧
  • 千问3.5-2B图文理解实战:从原始图输入到结构化JSON输出的完整数据管道设计
  • 2026洛阳江浙菜宴请选型指南:满足3个硬指标 - 精选优质企业推荐榜