三剑客——Sed

Sed 文本处理


前言

在文本处理的浩瀚海洋中,sed如同一位沉默而精准的雕刻家。它不创造文字,却赋予文字新的生命;不改变内容,却重塑内容的形式。作为流编辑器,sed以其独特的"模式空间"机制,在数据流的穿梭间完成着查找、替换、删除、插入的精妙操作。无论是系统日志的实时清洗,还是配置文件的批量调整;无论是千万行数据的模式提取,还是复杂文本的结构化转换,sed总能以一行命令的简洁,解决曾需手动重复的繁琐。它既是运维工程师的瑞士军刀,也是开发者的隐形助手,更是每个Linux使用者应当掌握的文本炼金术。

一、sed 简介与工作原理

1. 是什么
sed(Stream Editor,流编辑器)是一个利用脚本处理文本文件的强大工具。它能够根据预设的指令集自动编辑一个或多个文件,主要用于自动化编辑简化重复性文件操作编写文本转换程序

2. 核心原理:模式空间
sed 的核心在于 模式空间 (pattern space),这是一个临时的缓冲区。其工作流程如下:

  1. 读取:从输入流(文件、管道)中读取一行内容到模式空间。
  2. 执行:在模式空间中,按顺序执行所有 sed 命令。
  3. 显示:将处理后的模式空间内容输出到屏幕,然后清空缓冲区。
  4. 重复:读取下一行,重复上述过程,直至所有行处理完毕。

关键特性sed 默认不会修改源文件,所有操作结果只显示在标准输出。除非使用 -i 选项。


二、sed 基本语法与选项

1. 基本语法

sed [选项] '操作' 输入文件
sed [选项] -f 脚本文件 输入文件

2. 常用选项

  • -n:取消默认输出(不打印模式空间内容),常与 p 命令配合只打印匹配行。
  • -e:允许执行多个 sed 操作,用分号 ; 分隔。
  • -f:从指定脚本文件中读取 sed 操作。
  • -i[.后缀]直接修改源文件,可指定后缀来备份原文件(如 -i.bak)。
  • -r-E:启用扩展正则表达式,使 ( ), +, |, { } 等元字符无需转义。

3. 常用操作命令 (动作)

  • p:打印模式空间的内容。
  • d:删除模式空间的内容(即不输出)。
  • s/原字符串/新字符串/[标志]:搜索并替换(最核心的命令)。
  • a\文本:在指定行后追加一行文本。
  • i\文本:在指定行前插入一行文本。
  • c\文本:替换指定行的整行内容
  • y/原字符集/新字符集/:字符转换(类似 tr),按位置一一映射。
  • r 文件:将指定文件的内容读入,并追加到匹配行之后。
  • w 文件:将模式空间的内容写入指定文件。

三、sed 实战示例详解

1. 打印输出 (p 命令)

$ sed -n '3p' demo.txt
# 注释:`-n` 取消默认输出,`3p` 只打印第3行。不加 `-n` 会输出全部内容且第3行打印两次。

$ sed -n '1,5p' demo.txt
# 注释:打印第1到第5行(包含)。

$ sed -n '/error/p' system.log
# 注释:使用正则表达式,只打印包含 "error" 的行。

$ sed -n '2,/$p' demo.txt
# 注释:打印从第2行到文件末尾的所有行。

2. 删除文本 (d 命令)

$ sed '3d' demo.txt
# 注释:删除第3行(屏幕上不显示第3行),其他行正常输出。**源文件未被修改**。

$ sed '3,5d' demo.txt
# 注释:删除第3到第5行。

$ sed '/^#/d' config.conf
# 注释:删除所有以 `#` 开头的行(常用于删除配置文件中的注释)。

$ sed '/^$/d' demo.txt
# 注释:删除所有空行。

3. 搜索并替换 (s 命令)
这是 sed 最强大和最常用的功能。
基本语法s/原模式/替换字符串/[标志]
常用标志

  • g:全局替换(一行中所有匹配项都替换)。
  • 数字:替换第N个匹配项。
  • p:打印替换成功的行(常与 -n 联用)。
  • iI:忽略大小写。
$ sed 's/old/new/' file.txt
# 注释:将每行中**第一个** "old" 替换为 "new"。

$ sed 's/old/new/g' file.txt
# 注释:将每行中**所有**的 "old" 替换为 "new"。

$ sed 's/old/new/2' file.txt
# 注释:将每行中**第二个** "old" 替换为 "new"。

$ sed -n 's/root/ROOT/p' /etc/passwd
# 注释:只打印发生了替换操作的那些行。

$ sed -i.bak 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
# 注释:**直接修改源文件**,并将原文件备份为 `/etc/selinux/config.bak`。
# 这是生产环境中最常见的用法之一,用于自动化修改配置。

$ sed 's/^/# /' script.sh
# 注释:在每一行的行首插入 `# `(相当于给整个脚本注释)。

$ sed 's/\/usr\/local\/bin/\/usr\/bin/' path.conf
# 注释:替换路径。由于 `/` 是分隔符,需要用 `\` 转义,显得很混乱。
$ sed 's|/usr/local/bin|/usr/bin|' path.conf
# 注释:**使用其他分隔符**(如 `|`, `%`, `#`)可以避免转义的麻烦,使命令更清晰。

4. 行定位与范围操作
sed 命令可以指定单行、行范围或使用正则表达式来限定操作范围。

$ sed '5s/old/new/' file.txt
# 注释:只对第5行进行替换操作。

$ sed '3,7s/^/# /' file.txt
# 注释:在第3到第7行的行首添加 `# `。

$ sed '/start/,/end/d' file.txt
# 注释:删除从包含 "start" 的行开始,到包含 "end" 的行结束的所有行。

$ sed '/^server/{s/LOG/DEBUG/g; s/port=80/port=8080/}' app.conf
# 注释:对以 "server" 开头的行,执行**多个操作**(用分号 `;` 分隔):
# 1. 将所有 "LOG" 替换为 "DEBUG"。
# 2. 将 "port=80" 替换为 "port=8080"。

5. 插入与追加文本 (i\, a\ 命令)

$ sed '3i\这是新插入的行' demo.txt
# 注释:在第3行**之前**插入一行 "这是新插入的行"。

$ sed '$a\这是在文件末尾追加的行' demo.txt
# 注释:在文件**最后一行之后**追加一行。`$` 代表最后一行。

$ sed '/pattern/a\这是在匹配行后追加的文字' demo.txt
# 注释:在每一处匹配 "pattern" 的行**之后**追加一行。

6. 整行替换 (c\ 命令)

$ sed '/old_line/c\这是全新的内容' demo.txt
# 注释:将包含 "old_line" 的**整行**替换为 "这是全新的内容"。

7. 字符转换 (y 命令)

$ sed 'y/abc/ABC/' demo.txt
# 注释:将文件中所有的 `a` 替换为 `A`,`b` 替换为 `B`,`c` 替换为 `C`。
# 这是按字符一一映射的,类似 `tr` 命令。

8. 读写文件 (r, w 命令)

$ sed '/pattern/r other_file.txt' demo.txt
# 注释:在每一处匹配 "pattern" 的行后,插入 `other_file.txt` 的整个内容。

$ sed '/important/w saved_lines.txt' demo.txt
# 注释:将所有包含 "important" 的行,写入到 `saved_lines.txt` 文件中。

四、生产环境实战案例

案例1:修改网络配置IP地址

$ sed -i.bak 's/^IPADDR=.*/IPADDR=192.168.10.100/' /etc/sysconfig/network-scripts/ifcfg-ens33
# 注释:
# `-i.bak`:直接修改文件并创建备份 `ifcfg-ens33.bak`。
# `^IPADDR=.*`:匹配以 "IPADDR=" 开头的整行。
# `/IPADDR=192.168.10.100/`:将整行替换为新的IP地址配置。

案例2:从 ifconfig 中精确提取IP地址

$ ifconfig ens33 | sed -rn '2s/.*inet ([0-9.]+).*/\1/p'
# 注释:
# `-r`:使用扩展正则,避免对 `()` 转义。
# `2s`:只处理 `ifconfig` 输出的第二行(通常包含IPv4地址)。
# `.*inet ([0-9.]+).*`:匹配 "inet " 后面的一段IP地址(数字和点),并用 `()` 捕获。
# `\1`:引用第一个捕获组的内容,即纯IP地址。
# `p`:打印替换成功的结果。
# 最终只输出IP地址,如 `192.168.1.100`。

案例3:使用分组与反向引用

$ echo "123abcxyz" | sed -r 's/(123)(abc)(xyz)/\1---\3/'
123---xyz
# 注释:
# `-r`:启用扩展正则。
# `(123)`, `(abc)`, `(xyz)`:用括号分成三个组。
# `\1---\3`:在替换字符串中,`\1` 代表第一组 "123",`\3` 代表第三组 "xyz"。
# 结果是用 "---" 连接了第一组和第三组,跳过了第二组。

案例4:调整FTP服务配置(脚本示例)

#!/bin/bash
CONFIG="/etc/vsftpd/vsftpd.conf"
# 备份原配置
[ ! -e "$CONFIG.bak" ] && cp $CONFIG $CONFIG.bak
# 使用sed调整配置:禁止匿名用户,允许本地用户和写入
sed -i -e '/^anonymous_enable/s/YES/NO/' -e '/^local_enable/s/NO/YES/' -e '/^write_enable/s/NO/YES/' $CONFIG
# 注释:使用 `-e` 执行多个操作,每个操作都是针对以特定配置项开头的行进行精确替换。

总结

  • sed 的核心是 模式空间,它逐行处理文本。
  • -np 组合用于选择性打印
  • s 命令是搜索替换的利器,配合正则表达式功能强大。
  • 使用 -i 选项修改源文件前,务必确认或备份
  • 通过行号正则表达式范围可以精确限定操作目标。
  • 利用分组 ( )反向引用 \1 可以实现复杂的字符串重组。

总结

sed以其简洁的语法和强大的文本操控能力,完美诠释了Linux“小即是美”的哲学理念。它将复杂的文本处理化为优雅的命令组合,让我们在数据的河流中游刃有余。掌握sed,不仅是学会一个工具,更是获得了一种化繁为简的思维方式——用最精准的指令完成最复杂的编辑任务,这正是命令行艺术的精髓所在。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值