200字
文本处理三剑客-sed
2025-10-10
2025-10-10

"Stream Editor" 的缩写,是一个用于对文本流进行编辑的非交互式命令行工具。

该命令通过逐行读取文本、按预设规则(脚本或命令)处理内容(如替换、删除、插入、提取等),并输出处理结果,广泛用于日志分析、配置文件批量修改、脚本中的文本处理等场景,无需打开文件即可完成编辑操作。

 sed [选项] '编辑命令' <输入文件>
 # 或从标准输入读取(如管道传递)
 命令 | sed [选项] '编辑命令'

常用选项

  • -n:"no automatic print",禁止默认输出(默认情况下 sed 会输出所有行,包括未修改的行),仅显示被编辑命令匹配并处理的行,例如 sed -n '/error/p' log.txt 仅打印包含 "error" 的行。

  • -i:"in-place",直接修改原文件(而非输出到标准输出),是生产环境中批量修改文件的核心选项,例如 sed -i 's/old/new/' config.conf 直接替换 config.conf 中的内容;部分系统(如 macOS)需加备份后缀(如 -i.bak),修改后生成原文件备份(config.conf.bak)。

  • -e:"expression",指定多个编辑命令(可多次使用),例如 sed -e 's/a/A/' -e '/#/d' file.txt 先将 "a" 替换为 "A",再删除包含 "#" 的行。

  • -f:"file",从指定脚本文件中读取编辑命令,而非在命令行直接写,适合复杂的多步骤处理,例如 sed -f edit.sed data.txt 执行 edit.sed 中的所有编辑规则。

  • -r-E:"extended regular expressions",启用扩展正则表达式(无需对 +?() 等符号转义),例如 sed -r 's/(name)=.*/\1=Alice/' file.txt 用扩展正则匹配并替换。

  • -s:"separate files",将多个输入文件视为独立的文本流(而非合并为一个),处理时按文件分隔,例如 sed -s '1d' file1.txt file2.txt 分别删除 file1.txtfile2.txt 的第一行。

  • -v:"version",显示 sed 版本信息,例如 sed -v 查看当前系统的 sed 版本。

常用编辑命令(与选项配合使用) sed 的核心能力依赖「编辑命令」,格式通常为 [地址范围]命令[参数],常见命令如下:

  • s:"substitute",替换文本,格式 s/原字符串/新字符串/[标记],例如 s/old/new/(替换每行第一个 "old")、s/old/new/gg 标记:全局替换,每行所有 "old")、s/old/new/2(替换每行第二个 "old")。

  • d:"delete",删除行,例如 /^#/d 删除以 "#" 开头的行(注释行)、1,5d 删除第 1 到 5 行。

  • p:"print",打印行,需配合 -n 使用,例如 -n '/success/p' 打印包含 "success" 的行、-n '10,20p' 打印第 10 到 20 行。

  • i:"insert",在指定行前插入文本,例如 2i\Hello 在第 2 行前插入 "Hello"(部分系统需省略 \,直接 2iHello)。

  • a:"append",在指定行后追加文本,例如 /error/a\Check log 在包含 "error" 的行后追加 "Check log"。

  • c:"change",替换指定行的整行内容,例如 3c\New line 将第 3 行替换为 "New line"。

  • y:"translate",字符映射替换(按位置一对一替换),例如 y/abc/ABC/ 将所有 "a" 转 "A"、"b" 转 "B"、"c" 转 "C"。

参考示例

  • 示例1:批量替换配置文件中的参数 生产环境中修改 Nginx 配置的端口,执行 sed -i 's/listen 80;/listen 8080;/' /etc/nginx/nginx.conf,直接将配置中 "listen 80;" 替换为 "listen 8080;",无需手动打开文件编辑。

    提示:若需备份原文件(避免改错无法恢复),执行 sed -i.bak 's/listen 80;/listen 8080;/' /etc/nginx/nginx.conf,修改后生成 nginx.conf.bak 备份。

  • 示例2:提取日志中的错误信息并统计行数 分析应用日志 app.log,提取包含 "ERROR" 的行并统计数量,执行 sed -n '/ERROR/p' app.log | wc -l。其中 sed -n '/ERROR/p' 筛选错误行,管道传递给 wc -l 统计行数,快速定位问题规模。

  • 示例3:删除配置文件中的所有注释行和空行 清理 MySQL 配置文件 my.cnf 中的注释(# 开头)和空行,执行 sed -e '/^#/d' -e '/^$/d' my.cnf > my_clean.cnf-e '/^#/d' 删除注释行,-e '/^$/d' 删除空行,结果输出到新文件 my_clean.cnf,避免修改原文件。

  • 示例4:全局替换目录下所有文件中的关键词 批量修改项目中所有 .py 文件的 "old_func" 为 "new_func",执行 find ./src -name "*.py" -exec sed -i 's/old_func/new_func/g' {} \;find 找到所有目标文件,通过 -exec 调用 sed -i 全局替换,适合代码重构场景。

  • 示例5:在指定行前后插入内容/etc/hosts 文件中 "127.0.0.1 localhost" 行后追加 "127.0.0.1 test.local",执行 sed -i '/127.0.0.1 localhost/a\127.0.0.1 test.local' /etc/hosts,无需手动定位行号,按内容匹配插入,更灵活。

  • 示例6:用扩展正则批量提取日志中的 IP 地址 从访问日志 access.log 中提取所有 IP 地址(IPv4),执行 sed -nE 's/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).*/\1/p' access.log-E 启用扩展正则,([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+) 匹配 IP 地址并分组,\1 引用分组内容,仅输出 IP。

  • 示例7:在脚本中处理文本流(管道配合) 查看系统进程并筛选包含 "java" 的进程,仅保留进程 ID(PID),执行 ps aux | grep java | grep -v grep | sed -r 's/^[a-z0-9]+\s+([0-9]+).*/\1/'ps aux 输出所有进程,grep java 筛选 Java 进程,grep -v grep 排除自身,sed 提取 PID(第二列),便于后续批量杀进程(如 xargs kill -9)。

注意:1. 使用 -i 修改系统配置文件(如 /etc/passwd/etc/sysctl.conf)前,建议先备份(cp file file.bak),避免改错导致系统异常;2. Windows 格式文件(换行符 \r\n)在 Linux 下可能显示 ^M,可用 sed -i 's/\r//g' file.txt 清除;3. 正则中的特殊字符(如 .*/)需用 \ 转义,例如替换 "www.example.com" 需写 s/www\.example\.com/www.test.com/

评论