sed 命令进阶
sed 是面向行处理的,但是有时可能希望针对多行作为一个单位进行处理,在 sed 中这也是可行的,本文将介绍如何使用 sed 来同时处理多行文本
理论基础
模式空间(Pattern Space):是一块活跃的缓冲区,sed 命令处理行时都
会将文本行读入到该空间执行相关的脚本,默认情况下每次只会从输入中读取一行输入文本到该空间中进行处理。
保持空间(Hold Space):该空间的作用是临时保存 “模式空间” 中处理的文本行
由于 sed 一般是直接在 “模式空间” 中对文本数据进行处理的,因此如果能够改变 “模式空间” 读取文本数据的行为,即可实现将“多行文本数据作为一个处理单位进行处理” 的功能。而要改变 “模式空间” 的默认行为,可以通过 D、G、H、N、P等命令进行处理
多行文本处理
读取行
如果只是希望读取下一行,那么普通的 n 命令就可以做到,例如,如果希望将所有出现 “the” 的的行的下一行进行删除,可以执行如下的命令:
# n 命令读取下一行,d 命令进行删除
sed '/the/{n ; d}' data.txt
这里的 n 命令只会读取单行数据文本,然后进行对应的脚本进行处理,本质上在 “模式空间” 中还是只针对单行。如果要合并出现 ‘,’ 的两行,可以使用 N 命令来将读取到的文本行加入到 “模式空间” 中,如下所示:
# 注意将 \n 替换成空格,否则可能无法看到合并的结果
sed '/,/{N; s/\n/ /}' data.txt
注意: 由于 N 命令是获取下一行,因此如果处理的是最后一行的话,由于最后一行没有数据了,因此在读取到最后一行时,会停止 sed,使得最后一行的替换操作无法进行。
删除行
d 命令会删除匹配的行,当和 N 命令一起使用时可能不会达到你想要的结果,因此应该避免在使用 N 命令的同时使用 d 命令,为此可以考虑采用 D 命令来代替 d 命令进行删除
D 命令和 d 命令最大的不同在于 D 命令只会删除 “模式空间” 中的第一行,而不是将整个 “模式空间” 的所有文本行作为一个单元进行处理
D 命令的独特之处在于强制 sed 回到脚本的执行处,对同一 “模式空间” 中的内容重新执行这些脚本内容,
多行打印
当多行匹配时,通过 p 命令可以打印出当前匹配模式中存在的所有文本行,有时可能并不希望发生这样的行为,为此,可以通过 P 命令,该打印命令只会打印 “模式空间” 中的第一行文本内容
取反命令
可以通过在命令选项前加上 ! 来使得原有的命令无法生效,例如,前文提到,N 命令在处理最后一行时会关闭 sed,使得最后一行的内容无法被正确处理,为此,可以通过加入 ! 命令来禁用最后一行的行为,如下所示:
sed '$!N; s/the/a/' data.txt
现在,sed 就能够按照预期地将所有的文本行进行相关的处理
保持空间的相关操作
”保持空间“ 有以下五种选项进行对应的操作,如下表所示:
| 命令 | 描述 |
|---|---|
| h | 将模式空间中的内容复制到保持空间 |
| H | 将模式空间中的内容附加到保持空间 |
| g | 将保持空间中的内容复制到模式空间 |
| G | 将保持空间中的内容附加到模式空间 |
| x | 交换模式空间和保持空间的内容 |
例如,如果想要反向输出输入流中的文本内容,结合上文的取反命令,可以执行如下的脚本:
sed -n '1!G; h; $p' data.txt
解释:G 命令本身会将保持空间的内容附加到模式空间中,1G 的命令就是将保持空间的内容附加到模式空间的第一行,然而,加上 ! 排除命令之后,使得 1G 的行为变成反向附加到模式空间中;通过 h 命令将模式空间中的内容复制到保持空间;$p 表示每次当到达数据流的末尾时,打印模式空间中的内容
改变流
sed 通过顺序处理输入流来对每一行的数据执行对应的脚本,直到数据流结束(D 命令除外),sed 编辑器提供了一个方法来改变脚本的执行流程。
分支
分支的主要目的是排除某些文本行,使得它们不会执行对应的脚本,具体的使用格式如系所示:
[address]b [label]
例如,如果不希望 data.txt 中的 \([2,3]\) 的文本行不会执行替换脚本,可以执行类似如下的命令:
sed '2,3b; s/the/a/' data.txt
[label] 是类似 goto 语句的结构,如果希望当匹配到 first 文本时,跳转到执行不同的脚本,可以执行类似下面的命令:
sed '{/first/b jump1; s/This/No Jump/
:jump1
s/This/Jump Here/
}' data.txt
当匹配到 “first” 时,则会将执行将 ”This“ 替换为 ”Jump Here“ 的脚本,而不是替换成为 ”No Jump“
注意: 标签名的最大长度为 \(7\) 个字符
测试
和分支命令类似,测试命令 t(test)也可以用来改变 sed 编辑器脚本的执行流程,该命令和 if 语句类似。
使用格式如下:
[address]t [label]
例如,如下的脚本:
sed '{
s/first/matched/
t
s/This/No Matched/
}' data.txt
当处理的文本包含 ”first“ 时,会将 ”first“ 替换为 ”matched“,否则将该文本中的 ”This“ 替换为 ”No Matched“
测试命令 t 同样可以使用和分支类似的标签语义
模式替代
替换命令 s 已经十分了解,试想一下这样一种情况:希望为某个单词加上引号,似乎一般的 s 命令不能完美解决这个问题(无法知道匹配到的实际单词),为了解决这个问题,在传统的 Unix 中提供了 ‘&’ 符号用于表示匹配到的字符串,因此,如果希望给 ”the“ 加上引号,可以执行如下的脚本:
sed 's/th./"&"/' data.txt
有时可能希望替换掉一个字符串中的单词,那么可以考虑使用括号来进行单独的替换,括号表示一个子模式,如下所示:
# \1 表示匹配到的子模式
echo "This is System Administrator manual" | sed 's/\(System\).Administrator/\1 User/'
注意:子模式的括号需要使用 \ 进行转义,否则会被视为一般的字符
”\1“ 表示第一个括号的子模式,”\2“ 表示第二个括号的子模式…………
结合正则表达式可能使用得更加得心应手
参考:
[1] 《Linux 命令行与 Shell 脚本编程大全》
[2] https://www.gnu.org/software/sed/manual/sed.html
sed 命令进阶的更多相关文章
- sed命令总结-Linux
sed命令总结-Linux linuxsed 2018年02月08日 19时27分57秒 命令语法经常忘记,每次总是看笔记不切实际,记不起来的要多查manual,本次总结按照manual总结,希望下次 ...
- sed命令总结
目录 1.概述 2.查 1.打印整行(一或多) 2.正则打印包含关键字的行 2.增 3.删 4.改 5.后向引用 6.结合 7.练习 我叫张贺,贪财好色.一名合格的LINUX运维工程师,专注于LINU ...
- 文本处理三剑客之sed命令
第十八章.文本处理三剑客之sed命令 目录 sed介绍 sed命令常用选项 sed常用编辑命令 sed使用示例 sed高级语法 18.1.sed简介 sed全名stream editor,流编辑器,s ...
- linux shell 用sed命令在文本的行尾或行首添加字符
转自 http://www.cnblogs.com/aaronwxb/archive/2011/08/19/2145364.html 昨天写一个脚本花了一天的2/3的时间,而且大部分时间都耗在了sed ...
- linux sed命令详解
简介 sed 是一种在线编辑器,它一次处理一行内容.处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的 ...
- sed命令详解
搜索 纠正错误 添加实例 sed 功能强大的流式文本编辑器 补充说明 sed 是一种流编辑器,它是文本处理中非常中的工具,能够完美的配合正则表达式使用,功能不同凡响.处理时,把当前处理的行存储在临时 ...
- Linux安全基础:sed命令的使用
sed 是一个很好的文件处理工具,本身是一个管道命令,主要是以行为单位进行处理,可以将数据行进行替换.删除.新增.选取等特定工作. Sed本质上是一个编辑器,但是它是非交互式的,这点与VIM不同:同时 ...
- [转]sed命令详解
转载:http://blog.chinaunix.net/u/22677/showart_1076318.html 1.简介 sed是非交互式的编辑器.它不会修改文件,除非使用shell重定向来保 ...
- sed命令
sed是一个很好的文件处理工具,本身是一个管道命令,主要是以行为单位进行处理,可以将数据行进行替换.删除.新增.选取等特定工作,下面先了解一下sed的用法sed命令行格式为: sed ...
- sed 命令使用
ios 的sed 命令 跟linux sed 命令有区别 # 所有的a 替换成b sed -i "" 's/a/b/g' #删除掉所有包含a的行 sed -i "/a/ ...
随机推荐
- 【Flutter】如何优美地实现一个悬浮NavigationBar
[Flutter]如何优美地实现一个悬浮NavigationBar 最近写代码的时候遇到了一个如下的需求: 整体来说,底部的条是一个浮动的悬浮窗,有如下的三个按钮: 点击左边的要进入"主页& ...
- RedisStack部署/持久化/安全/与C#项目集成
前言 Redis可好用了,速度快,支持的数据类型又多,最主要的是现在可以用来向量搜索了. 本文记录一下官方提供的 redis-stack 部署和配置过程. 关于 redis-stack redis-s ...
- 前端三件套系例之BootStrap——BootStrap基础、 BootStrap布局
文章目录 1 BootStrap基础 1 什么是BootStrap 2 BootStrap的版本 3 BootStrap 下载 4 CDN服务 5 目录结构 6 基本模板 7 浏览器支持 8 浏览器兼 ...
- 如何基于three.js(webgl)引擎架构,研发一套通过配置就能自动生成的3D机房系统
序: 这几年观察下来,大部分做物联网三维可视化解决方案的企业或个人, 基本都绕不开3D机房.包括前面也讲过这样的案例<使用webgl(three.js)创建自动化抽象化3D机房,3D机房模块详细 ...
- Avalonia 实现视频聊天、远程桌面(源码,支持Windows、Linux、国产OS)
现在最火的.NET跨平台UI框架莫过于Avalonia了.Avalonia 基于.NET Core,因此它可以运行在任何支持.NET Core的平台上.之前基于CPF跨平台UI框架写过一个视频聊天的d ...
- 再学Blazor——扩展方法
上篇提到 Blazor 组件的高级写法,是采用扩展方法对 HTML 元素和组件进行扩展,以便于书写组件结构和代码阅读.本篇主要介绍扩展方法实现的思路. 什么是扩展方法 要扩展哪个类 扩展方法的实现 1 ...
- 【原型链污染】Python与Js
[原型链污染]Python与Js 一.背景 最近在TSCTF的比赛题中遇到了Python的原型链污染题目,所以借此机会学习一下.说到原型链,最多的还是在Js中,所以就一并学习一下.(因为是菜鸡所以文章 ...
- 关于Android Stuido2.3和Eclipse4.4
近3年没有做Android开发了,当时用是ECLISPE电脑配置2g,用的还可以. 现在又重新开始做安卓程序,发现大家都用AS了,作为技术人员,也就开始用了. (几年前AS已经发布,不过是0.x版本, ...
- 虹科干货 | 什么是Redis数据集成(RDI)?
大量的应用程序.日益增长的用户规模.不断扩展的技术需求,以及对即时响应的持续追求.想想这些是否正是你在经历的.也许你尝试过自己构建工具来应对这些需求,但是大量的编码和集成工作使你焦头烂额.那你是否知道 ...
- KingabseES例程-事实数据与规则的匹配校验
KingabseES例程-事实数据与规则的匹配校验 背景 使用规则,对数据进行校验,比如电商的用户购物订单,是否合法.这就需要订单的多维度,如 用户.地区.物流.支付手段.供应商 等各类信息,进行动态 ...