sed 流编辑器练习自用

sed 流编辑器完全指南

一、概述

什么是 sed?

sed(Stream Editor,流编辑器)是 Unix/Linux 系统中的非交互式文本编辑器,用于对输入流(文件或管道)进行基于文本的转换。它按行处理文本,是文本处理的瑞士军刀。

核心特点

  • 非交互式:通过命令行参数或脚本执行,无需人工干预

  • 流式处理:逐行读取、处理、输出,内存占用小

  • 强大的正则表达式支持:支持基本和扩展正则表达式

  • 脚本化:可编写 sed 脚本文件,实现复杂处理

  • 高效快速:纯文本处理时性能优于大多数脚本语言

二、基本语法

bash 复制代码
# 基本格式
sed [选项] '命令' 输入文件
sed [选项] -f 脚本文件 输入文件

# 管道使用
cat 文件 | sed [选项] '命令'
命令输出 | sed [选项] '命令'

三、常用选项详解

选项 说明 示例
-n 静默模式,只输出处理过的行(常与 p 命令配合) sed -n '1,5p' file.txt
-e 指定多个编辑命令 sed -e 's/a/A/' -e 's/b/B/' file.txt
-f 从脚本文件读取 sed 命令 sed -f script.sed file.txt
-i[扩展名] 直接修改原文件(加扩展名则备份) sed -i.bak 's/foo/bar/' file.txt
-r (GNU) 启用扩展正则表达式 sed -r 's/(ab)+/X/g' file.txt
-E (BSD/macOS) 启用扩展正则表达式 sed -E 's/(ab)+/X/g' file.txt
--version 显示版本信息 sed --version
--help 显示帮助信息 sed --help

四、核心命令完全参考

1. 文本替换 (s 命令)

bash 复制代码
# 基本语法
s/正则表达式/替换文本/标志

# 常用示例
sed 's/old/new/' file.txt              # 每行第一个匹配替换
sed 's/old/new/g' file.txt             # 全局替换(所有匹配)
sed 's/old/new/2' file.txt             # 每行第2个匹配替换
sed 's/old/new/ig' file.txt            # 忽略大小写并全局替换

# 标志说明
g - 全局替换(所有匹配)
i - 忽略大小写
p - 打印替换成功的行(常与 -n 合用)
w 文件 - 将替换成功的行写入文件

# 高级示例
sed -n 's/pattern/replacement/pw output.txt' file.txt
sed 's/pattern/replacement/2g' file.txt  # 从第2个开始全局替换

2. 删除行 (d 命令)

bash 复制代码
# 基本删除
sed '3d' file.txt                      # 删除第3行
sed '3,7d' file.txt                    # 删除3-7行
sed '3,+5d' file.txt                   # 从第3行开始删除6行
sed '$d' file.txt                      # 删除最后一行
sed '1~2d' file.txt                    # 删除奇数行(从第1行开始,每隔1行删除)

# 模式匹配删除
sed '/pattern/d' file.txt              # 删除匹配行
sed '/^#/d' file.txt                   # 删除注释行(#开头)
sed '/^$/d' file.txt                   # 删除空行
sed '/^\s*$/d' file.txt                # 删除空白行(空格/tab组成)

# 范围删除
sed '/start/,/end/d' file.txt          # 删除从start到end的所有行
sed '10,/end/d' file.txt               # 从第10行删除到匹配end的行

3. 打印 (p 命令)

bash 复制代码
# 基本打印(常与 -n 选项配合)
sed -n '3p' file.txt                   # 只打印第3行
sed -n '3,7p' file.txt                 # 打印3-7行
sed -n '10,$p' file.txt                # 从第10行打印到最后
sed -n '/pattern/p' file.txt           # 打印匹配行

# 范围打印
sed -n '/start/,/end/p' file.txt       # 打印start到end的所有行
sed -n '/pattern/,+3p' file.txt        # 打印匹配行及其后3行

4. 插入/追加/替换行

bash 复制代码
# 插入行 (i - 在指定行前插入)
sed '3i\插入的内容' file.txt           # 在第3行前插入
sed '/pattern/i\插入的内容' file.txt    # 在匹配行前插入
sed '3i第一行\n第二行' file.txt         # 插入多行(使用\n分隔)

# 追加行 (a - 在指定行后追加)
sed '3a\追加的内容' file.txt           # 在第3行后追加
sed '/pattern/a\追加的内容' file.txt    # 在匹配行后追加
sed '$a\文件末尾追加' file.txt          # 在文件末尾追加

# 替换行 (c - 替换整行)
sed '3c\替换为这行' file.txt           # 替换第3行
sed '/pattern/c\新行内容' file.txt     # 替换匹配行
sed '2,4c\替换为一行' file.txt         # 将2-4行替换为一行

# 注意:BSD/macOS sed 需要额外的换行符
sed -i '' '3i\
插入的内容' file.txt

5. 文件读写操作

bash 复制代码
# 读取文件 (r - 将文件内容插入)
sed '3r otherfile.txt' file.txt        # 在第3行后插入文件内容
sed '/pattern/r otherfile.txt' file.txt # 在匹配行后插入
sed '$r otherfile.txt' file.txt        # 在文件末尾追加文件内容

# 写入文件 (w - 将行写入文件)
sed -n '/pattern/w output.txt' file.txt # 将匹配行写入文件
sed '1,10w part1.txt' file.txt         # 将1-10行写入文件
sed -n 'w output.txt' file.txt         # 写入所有行(相当于cp)

# 示例:分割文件
sed -n '1,100w part1.txt' file.txt
sed -n '101,200w part2.txt' file.txt

6. 字符转换 (y 命令)

bash 复制代码
# 语法:y/源字符集/目标字符集/
sed 'y/abc/ABC/' file.txt             # a→A, b→B, c→C(一一对应)
sed 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' file.txt  # 转大写
sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/' file.txt  # 转小写

# 注意:y命令处理的是字符,不是字符串

7. 多命令执行

bash 复制代码
# 方法1:使用 -e 选项
sed -e 's/foo/bar/' -e '/baz/d' file.txt

# 方法2:使用分号分隔
sed 's/foo/bar/; /baz/d' file.txt

# 方法3:多行命令(使用反斜杠续行)
sed '
s/foo/bar/
s/baz/qux/
/pattern/d
' file.txt

# 方法4:使用脚本文件
echo "s/foo/bar/" > script.sed
echo "/baz/d" >> script.sed
sed -f script.sed file.txt

五、高级功能与技巧

1. 模式空间与保持空间

bash 复制代码
# 保持空间相关命令
h  # 将模式空间复制到保持空间(覆盖)
H  # 将模式空间追加到保持空间
g  # 将保持空间复制到模式空间(覆盖)
G  # 将保持空间追加到模式空间
x  # 交换模式空间和保持空间

# 示例:反转文件行顺序
sed -n '1!G; h; $p' file.txt

# 示例:合并相邻行
sed 'N; s/\n/ /' file.txt              # 将两行合并为一行

2. 条件分支与跳转

bash 复制代码
# 定义标签和跳转
:label_name       # 定义标签
b label_name      # 无条件跳转到标签
t label_name      # 如果发生替换则跳转
T label_name      # 如果没发生替换则跳转

# 示例:跳过特定行的处理
sed '/^#/b; s/foo/bar/' file.txt      # 注释行不执行替换

# 示例:循环处理
sed ':a; s/foo/bar/; ta' file.txt     # 重复替换直到没有更多匹配

3. 行号处理

bash 复制代码
# 显示行号
sed '=' file.txt                      # 每行前显示行号
sed -n '=' file.txt                   # 只显示行号
sed -n '$=' file.txt                  # 显示总行数

# 示例:显示行号及内容
sed '=' file.txt | sed 'N; s/\n/:/'   # 格式:行号:内容

# 示例:处理特定行号范围
sed '10,20 {                         # 对10-20行执行多个操作
    s/foo/bar/g
    /baz/d
}' file.txt

4. 分组与反向引用

bash 复制代码
# 使用括号分组和反向引用(需要 -r 或 -E)
sed -r 's/(foo)(bar)/\2\1/' file.txt  # 交换foo和bar
sed -r 's/([0-9]{3})-([0-9]{3})-([0-9]{4})/(\1) \2-\3/' file.txt  # 格式化电话

# 示例:提取和重组
echo "John Doe,30,Engineer" | sed -r 's/([^,]*),([^,]*),([^,]*)/姓名:\1, 年龄:\2, 职位:\3/'

基础练习

题目1:简单替换

文件 data1.txt 内容:

复制代码
apple orange apple
banana apple grape
orange banana orange

要求:

  1. 将所有 "apple" 替换为 "fruit"

  2. 只替换每行第一个 "apple"

  3. 只替换每行第二个 "orange"

bash 复制代码
sed -i 's/apple/fruit/g' data1.txt
sed -i 's/apple/fruit' data1.txt
sed -i 's/apple/fruit/2' data1.txt

题目2:行操作

文件 data2.txt 内容:

复制代码
Line 1: First line
Line 2: Second line
Line 3: Third line
Line 4: Fourth line
Line 5: Fifth line

要求:

  1. 删除第3行

  2. 删除第2-4行

  3. 在 "Third line" 前插入 "INSERTED LINE"

  4. 在最后一行后追加 "APPENDED LINE"

sed -i '3d' data2.txt

sed -i '2,4d' data2.txt

sed '3a\APPENDED' data2.txt

题目3:模式匹配

文件 config.txt 内容:

复制代码
# Server configuration
server_name = localhost
port = 8080
# Database settings
db_host = 127.0.0.1
db_port = 3306
# End of config

要求:

  1. 删除所有注释行(以 # 开头)

  2. 删除空行

  3. 只显示包含 "port" 的行

sed '/^#/d' config.txt

sed '/ /d' config.txt 错了这是删除空格的行! 正确:sed '/^$/d' config.txt

sed -n '/port/p' config.txt 没有考虑大小写 正确:sed -n '/port/ip' config.txt

中级练习

题目4:提取数据

文件 log.txt 内容:

复制代码
2023-10-01 10:00:01 INFO User login: john@example.com
2023-10-01 10:00:05 ERROR Database connection failed
2023-10-01 10:00:10 INFO File uploaded: report.pdf
2023-10-01 10:00:15 WARNING Disk space low
2023-10-01 10:00:20 INFO User logout: john@example.com

要求:

  1. 提取所有 ERROR 行

  2. 提取时间戳(格式:10:00:01)

  3. 提取邮箱地址

  4. 提取文件名(不含路径)

sed -n '/ERROR/p' log.txt

sed -n 's/.* \([0-9]\{2\}:[0-9]\{2\}:[0-9]\{2\}\) .*/\1/p' log.txt

sed -n 's/.* \([^ ]*@[^ ]*\.[^ ]*\) .*/\1/p' log.txt

sed -n 's/.* \([^/ ]\+\)$/\1/p' log.txt

题目5:格式转换

文件 contacts.csv 内容:

复制代码
"John Doe","john@example.com","555-1234"
"Jane Smith","jane@example.com","555-5678"
"Bob Johnson","bob@example.com","555-9012"

要求:

  1. 删除所有引号

  2. 将逗号分隔转换为管道分隔

  3. 转换格式为:姓名: <name>, 邮箱: <email>, 电话: <phone>

  4. 只显示姓名和邮箱

sed '/"/ /g' contacts.csv

sed 's/"//g; s/,/|/g' contacts.csv

sed 's/"//g' contacts.csv | awk -F, '{print "姓名: "1", 邮箱: "2", 电话: "$3}'

sed 's/"//g' contacts.csv | awk -F, '{print "姓名: "1", 邮箱: "2}'

相关推荐
靈龍靈2 小时前
ELBK部署
运维·ci/cd·jenkins
智象科技2 小时前
从资源到业务:运维监控体系的差异
大数据·运维·一体化运维·智能运维·多云管理
大志若愚YYZ2 小时前
嵌入式Linux初探索——点灯背后的驱动层与应用层及其交互
linux
杜子不疼.2 小时前
【Linux】多机管理终极方案:禁用 root 密码,用面板实现批量部署 + 操作追溯
linux·运维·服务器
艾莉丝努力练剑2 小时前
【Python基础:语法第五课】Python字典高效使用指南:避开KeyError,掌握遍历与增删改查精髓
大数据·运维·人工智能·python·安全·pycharm
后端小张2 小时前
【JAVA进阶】Docker 2025完全指南:从容器入门到企业级实践
java·运维·开发语言·spring·docker·容器·springboot
Ronin3052 小时前
【Linux网络】五种IO模型与非阻塞IO
linux·网络·非阻塞io·五种io模型
刚入门的大一新生2 小时前
Linux-Linux初识与基础指令
linux
DeepFlow 零侵扰全栈可观测2 小时前
金山办公基于 DeepFlow docker 模式的可观测性实践
运维·docker·容器