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

【shell编程知识点汇总】第九章 HTML 清洗、多行合并与条件替换

目录

一、HTML 标签清洗:剥离尖括号内容

二、多行合并:N 命令与换行符替换

三、逻辑取反:! 的否定语义

四、匹配整体引用:& 的替身魔法

五、精准定位:只输出最后一行

六、地址限定替换:条件化编辑

总结速查表

结语


在文本处理中,sed不仅是简单的查找替换工具,更是能够处理结构化文本、执行条件逻辑的行级编辑器。本文针对六个高阶场景——从 HTML 标签清洗到地址限定替换——深入解析其内部机制,帮助你日志分析、数据清洗和配置管理。


一、HTML 标签清洗:剥离尖括号内容

问题:sed 's/<[^>]*>//g'这个正则模式主要用来去除什么?

解析:

这是 sed 中经典的HTML/XML 标签去除模式,用于将文本中的所有 HTML 标签剥离,仅保留纯文本内容。

正则拆解:

模式含义
<匹配左尖括号(标签起始)
[^>]*匹配从当前位置开始,一直到第一个>之前的所有内容(不含>本身)。
>匹配右尖括号(标签结束)
//替换为空(删除)
g全局标志,处理行内所有标签

工作原理:

[^>]*是一个否定字符类,它贪婪地匹配标签内的所有属性、样式和文本,直到遇到第一个>为止。配合g标志,一行内出现的多个标签都会被依次移除。

示例:

echo '<p class="intro">Hello <b>World</b>!</p>' | sed 's/<[^>]*>//g' # 输出:Hello World! #这里 s/<[^>]*>//g:把所有 HTML 标签替换成空字符串 #HTML 标签比如:<p>、<p class="intro">、<b>、</b>、</p> 全都能匹配到。

⚠️ 注意事项:

此模式适用于简单、格式规范的 HTML。对于嵌套复杂、包含>在属性值中(如data-val="a>b")或跨行标签的情况,sed 的单行处理能力可能力不从心,此时建议使用专门的 HTML 解析器。


二、多行合并:N命令与换行符替换

问题:sed 'N; s/\n/ /'其中的N命令和\n的替换实现了什么样的行操作?

解析:

该命令实现了将相邻的两行合并为一行,并用空格替代原有的换行符。

核心机制:

  • N(Next):将输入流的下一行追加到当前模式空间(pattern space),两行之间以换行符\n分隔

  • s/\n/ /:将模式空间中的换行符替换为空格,完成行合并

执行流程示例:

# 输入: # Hello # World sed 'N; s/\n/ /' file.txt # 输出: # Hello World

进阶理解:

N是 sed 处理多行模式空间的关键命令。默认情况下 sed 逐行处理,但N允许你将多行加载到同一个模式空间进行跨行操作。类似的命令还有:

  • P:打印模式空间中第一行(到第一个\n为止)

  • D:删除模式空间中第一行,并重新开始循环

循环合并多行:

如果需要将所有行合并为一行,可以配合标签实现循环:

sed ':a; N; s/\n/ /; ta' file.txt #:a定义一个标签 a(相当于循环的起点)。

三、逻辑取反:!的否定语义

问题:sed '/foo/!d' file.txt中的感叹号!表示什么逻辑?

解析:

!表示逻辑取反(negation),即"对不匹配地址的行执行后续命令"。

完整解读:

  • /foo/:地址条件,匹配包含字符串foo的行

  • !:否定该地址条件

  • d:删除命令

因此,/foo/!d的含义是:删除所有不包含foo的行,最终只保留包含foo的行。

等价命令:

sed '/foo/!d' file.txt # 完全等价于: sed -n '/foo/p' file.txt #默认 sed 会输出所有行 #加 -n = 只输出我们指定的行 #p print = 打印匹配到的行

!的通用性:

!可以应用于任何命令和地址组合,例如:

sed '5!s/foo/bar/' # 除第5行外,其他行中的 foo 替换为 bar sed '$!d' # 删除除最后一行外的所有行(仅保留最后一行) #$ :匹配最后一行 ! :取反,不是最后一行 d :delete,删除当前行

四、匹配整体引用:&的替身魔法

问题:解释sed 's/./& /g'中符号&代表什么内容?

解析:

&在 sed 的替换字符串中表示整个正则表达式匹配到的完整文本(即匹配模式的"镜像")。

命令拆解:

  • .:匹配任意单个字符(包括空格、标点等)

  • &:在替换部分,&被替换为刚才匹配到的那个字符,后面再加一个空格

  • g:全局执行,对每行中每个字符都操作

效果演示:

echo "Hello" | sed 's/./& /g' # 输出:H e l l o

&的典型应用场景:

  1. 给匹配内容加标记

echo "price: 100" | sed 's/[0-9]\+/[&]/' # 把文本里的第一个数字用方括号 [] 包起来。 # \+:匹配一个或多个(+ 在 sed 里需要转义写成 \+) # &:引用匹配到的内容 # 输出:price: [100]
  1. 重复匹配内容

echo "abc" | sed 's/.*/& &/' # 输出:abc abc # .*:正则,匹配整行所有字符
  1. 与反向引用的区别

  • &:引用整个匹配串

  • \1,\2...:引用捕获组(括号内的部分)


五、精准定位:只输出最后一行

问题:sed -n '$p' file.txt只会输出文件的哪一部分?

解析:

该命令仅输出文件的最后一行

符号解析:

符号含义
-n静默模式,抑制默认的逐行打印行为
$特殊地址,代表最后一行(Last Line)
p显式打印命令

工作流程:

sed 逐行读取文件,-n确保不自动输出任何内容。当读取到最后一行时,$地址匹配成功,触发p命令将其打印。

等效命令对比:

sed -n '$p' file.txt # sed 方式 tail -n 1 file.txt # tail 方式 awk 'END{print}' file.txt # awk 方式

扩展:倒数第 N 行

sed 本身没有直接支持倒数第 N 行的内置地址,但可以通过保持空间(hold space)或结合其他命令实现:

# 输出倒数第3行 sed -n ':a; N; 4,$D; ba' file.txt
  • -n安静模式,不自动输出任何行

  • :a定义一个标签 a,循环的起点。

  • N读取下一行,追加到模式空间(缓冲区)。

  • 4,$D

    • 4,$:从第 4 行最后一行
    • D:删除模式空间第一行
    • 意思:只要缓冲区里 ≥4 行,就删掉最旧的那一行
  • ba无条件跳回标签 a,继续循环。

  • 读第 1 行 → 缓存:[1]
  • 读第 2 行 → 缓存:[1,2]
  • 读第 3 行 → 缓存:[1,2,3]
  • 读第 4 行 → 缓存≥4 行 →删第 1 行→ 缓存:[2,3,4]
  • 读第 5 行 → 缓存≥4 行 →删第 2 行→ 缓存:[3,4,5]
  • ... 一直到文件结束
  • 最后缓存里剩下的就是最后 3 行

六、地址限定替换:条件化编辑

问题:sed '/Error/s/False/True/'中,替换操作s是在所有行执行,还是受限于前面的地址?

解析:

替换操作受限于前面的地址,只有匹配/Error/的行才会执行s/False/True/

地址-命令结构:

sed 的命令格式为[address[,address]]command。当命令前带有地址时,该命令仅对地址匹配的行生效。

执行逻辑:

  1. sed 逐行读取输入

  2. 检查当前行是否包含字符串Error

  3. 如果包含:执行s/False/True/(将该行中的False替换为True

  4. 如果不包含:跳过s命令,该行原样输出(除非有其他命令)

示例演示:

# 输入: # Status: OK, Result: False # Status: Error, Result: False # Status: Warning, Result: False sed '/Error/s/False/True/' file.txt # 输出: # Status: OK, Result: False # Status: Error, Result: True # Status: Warning, Result: False

复合地址应用:

地址限定可以与范围、正则、行号灵活组合:

sed '5,10s/foo/bar/' # 仅第5到10行执行替换 sed '/BEGIN/,/END/s/x/y/' # 仅BEGIN到END范围内的行执行替换 sed '/^#/!s/^/ /' # 对非注释行缩进两个空格 # /^#/:匹配以 # 开头的注释行 # !:取反 → 不是注释行 # s/^/ /:行首插入两个空格

总结速查表

问题核心知识点一句话总结
1s/<[^>]*>//g删除 HTML/XML 标签,提取纯文本
2N; s/\n/ /加载下一行到模式空间,将换行转为空格合并行
3/foo/!d!取反,只保留匹配行,删除其余行
4s/./& /g&代表完整匹配串,给每个字符后加空格
5-n '$p'-n配合$p,精确输出文件最后一行
6/Error/s/.../地址限定命令作用域,仅匹配行执行替换

结语

sed 的魅力在于其地址-命令模型的简洁与强大。通过地址筛选目标行,再通过命令执行精确编辑,这种"先定位、后操作"的范式,使得 sed 在处理日志过滤、配置修改、数据格式化等任务时极为高效。

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

相关文章:

  • 说说Markdown为什么不会被HTML取代
  • KMS_VL_ALL_AIO:智能激活解决方案完全解析
  • 第6章:C++ Sanitizer全家桶实战
  • day22_深度学习入门与pytorch
  • 程序员的副业天花板:靠接私活实现年入百万的秘诀
  • AI智能体技能库开发指南:从原理到实战构建高效Agent应用
  • 苍穹外卖开发日记-微信登录
  • 2026年5月更新:美甲产业升级,甲片专用机定制厂家遴选全攻略 - 2026年企业推荐榜
  • PKSM终极指南:从菜鸟到宝可梦存档管理大师的完整路径
  • Dify插件重打包工具:标准化分发与一键部署实践
  • SPI长距离通信的时钟同步与信号完整性优化
  • 从零上手VibeCoding(ClaudeCode+DeepSeek V4.Pro)
  • 0. 深度学习课程大纲:
  • Redis 身份迷失
  • 从“边缘人”到香饽饽:35岁程序员的开源逆袭路
  • 《我的世界》Java版客户端模组开发:基于freedom-for-steve框架的底层定制实践
  • 【ElevenLabs有声书制作黄金法则】:20年音频工程师亲授,零基础7天交付商用级有声书
  • Node 版本升级后 Electron 原生模块编译失败怎么解决
  • AI工程化实战:从模型到服务的全链路部署与优化指南
  • 手摸手教你用Claude多智能体,零代码构建专属“超级办公助理”全过程
  • Claw-ED:基于Python的配置驱动Web爬虫框架实战指南
  • Gemini CLI提示词库:AI辅助开发提效的工程化实践
  • 为你的开源项目集成多模型能力,Taotoken接入方案详解
  • 基于MCP协议构建AI工具调用客户端:原理、实践与Node.js实现
  • 代码随想录算法训练营Day-50 图论02 | 99.岛屿数量-深搜、99.岛屿数量-广搜 、100.岛屿的最大面积
  • 基于Node.js的静态博客生成器:从零构建自动化内容流水线
  • 从英文恐惧到设计自信:一个产品设计师的Axure中文界面改造之旅
  • RS-485与RS-422工业通信技术详解与应用实践
  • SciDownl终极指南:5步高效获取学术文献的完整教程
  • 脚本的下一站:让自然语言直接成为可执行入口