通过几个例子看sed的模式空间与保持空间

 

SED之所以能以行为单位的编辑或修改文本,其原因在于它使用了两个空间:一个是活动的“模式空间(pattern space)”,另一个是起辅助作用的“暂存缓冲区(holdingspace)这2个空间的使用。

 

sed编辑器逐行处理文件,并将输出结果打印到屏幕上。sed命令将当前处理的行读入模式空间(pattern space)进行处理,sed在该行上执行完所有命令后就将处理好的行打印到屏幕上(除非之前的命令删除了该行),sed处理完一行就将其从模式空间中删除,然后将下一行读入模式空间,进行处理、显示。处理完文件的最后一行,sed便结束运行。sed在临时缓冲区(模式空间)对文件进行处理,所以不会修改原文件,除非显示指明-i选项。

 

sed之所以能以行为单位的编辑或修改文本,其原因在于它使用了两个空间:一个是活动的“模式空间(pattern space)”,另一个是起辅助作用的“保持空间(hold space)这2个空间的使用。

 

模式空间:可以想成工程里面的流水线,数据之间在它上面进行处理,用于处理文本行。

 

保持空间:可以想象成仓库,我们在进行数据处理的时候,作为数据的暂存区域,用于保留文本行,是保存已经处理过的输入行,默认有一个空行。 

 

与模式空间和暂存空间(hold space)相关的命令:

 

n 输出模式空间行,读取下一行替换当前模式空间的行,执行下一条处理命令而非第一条命令。

 

N 读入下一行,追加到模式空间行后面,此时模式空间有两行。

 

h 把模式空间的内容复制到保留空间,覆盖模式

 

H 把模式空间的内容追加到保留空间,追加模式

 

g 把保留空间的内容复制到模式空间,覆盖模式

 

G 把保留空间的内容追加到模式空间,追加模式

 

x 将暂存空间的内容于模式空间里的当前行互换。

 

! 对所选行以外的所有行应用命令。

 

 

 

注意:暂存空间里默认存储一个空行。

 

 

例子一 
sed G 
在文件每一行下面输出一个空行 

代码:

$ cat foo 
11111111111111 
22222222222222 
33333333333333 
44444444444444 
55555555555555 

$ sed G foo 
11111111111111 

22222222222222 

33333333333333 

44444444444444 

55555555555555 


解释: 

sed 中 G 的用法 
The G function appends the contents of the holding area to the contents of the pattern space. The former and new contents are separated by a newline. The maximum number of addresses is two. 

hold space : 保持空间(或者叫保留空间、缓冲区),初始为空 
pattern space :模式空间 

在上面的例子中,将为空的hold space附加到文件的每一行后面,所以结果是每一行后面多了一个空行 

引申出: 
sed '/^$/d;G' 
在文件的每一个非空行下面输出一个空行 
sed '/^$/d;G;G' 
在文件的每一个非空行下面输出两个空行 

代码:

$ cat foo 
11111111111111 
22222222222222 

33333333333333 
44444444444444 
55555555555555 

$ sed '/^$/d;G' foo 
11111111111111 

22222222222222 

33333333333333 

44444444444444 

55555555555555 



注:有时会有一些由空格符或者TAB组成的空行,前面的正则式 ^$ 就不能匹配到这样的行,则可以这样 
sed '/[[:space:]]/d;G' 


例子二 
sed '/regex/{x;p;x;}' 
在匹配regex的所有行前面插入一个空行 
代码:

$ cat foo 
11111111111111 
22222222222222 
test33333333333333 
44444444444444 
55555555555555 

$ sed '/test/{x;p;x;}' foo 
11111111111111 
22222222222222 

test33333333333333 
44444444444444 
55555555555555 


解释: 
sed 中 x 的用法 
The exchange function interchanges the contents of the pattern space and the holding area. The maximum number of addresses is two. 
即交换保持空间hold space和模式空间pattern space的内容 

sed 中 p 的作用是把模式空间复制到标准输出。 

分析一下该命令执行过程中保持空间和模式空间的内容 

命令 保持空间 模式空间 
x 执行前:null 执行后:test\n 执行前:test\n 执行后:null 
p 执行前:null 执行后:test\n 执行前:test\n 执行后:null 输出一个空行 
x 执行前:test\n 执行后:null 执行前:null 执行后:test\n 

(注:把test所在的行简写为test了) 

引申: 
可以试验一下 sed '/test/{x;p;}' foo 或者 sed '/test/{p;x;}' foo 等,看看结果,体会两个空间的变化 

相应的: 
sed '/regex/G' 是在匹配regex的所有行下面输出一个空行 
sed '/regex/{x;p;x;G;}' 是在匹配regex的所有行前面和下面都输出一个空行 


例子三 
sed 'n;G;' 
在文件的偶数行下面插入一个空行 
代码:

$ cat foo 
11111111111111 
22222222222222 
33333333333333 
44444444444444 
55555555555555 

$ sed 'n;G;' foo 
11111111111111 
22222222222222 

33333333333333 
44444444444444 

55555555555555 

解释: 
sed 中 n 的用法:将模式空间拷贝于标准输出。用输入的下一行替换模式空间。 

执行 n 以后将第一行输出到标准输出以后,然后第二行进入模式空间,根据前面对 G 的解释,会在第二行后面插入一个空行,然后输出;再执行 n 将第三行输出到标准输出,然后第四行进入模式空间,并插入空行,依此类推 

相应的: 
sed 'n;n;G' 表示在文件的第 3,6,9,12,... 行后面插入一个空行 
sed 'n;n;n;G' 表示在文件的第 4,8,12,16,... 行后面插入一个空行 
sed 'n;d' 表示删除文件的偶数行 


例子四 
sed '$!N;$!D' 
输出文件最后2行,相当于 tail -2 foo 

代码:

$ cat foo 
11111111111111 
22222222222222 
33333333333333 
44444444444444 
55555555555555 

$ sed '$!N;$!D' foo 
44444444444444 
55555555555555 



解释: 

D 删除模式空间内第一个 newline 字母 \n 前的资料。 
N 把输入的下一行添加到模式空间中。 

sed '$!N;$!D' : 对文件倒数第二行以前的行来说,N 将当前行的下一行放到模式空间中以后,D 就将模式空间的内容删除了;到倒数第二行的时候,将最后一行附加到倒数第二行下面,然后最后一行不执行 D ,所以文件的最后两行都保存下来了。 


还有 N 的另外一种用法 
代码:

$ sed = foo | sed N 

11111111111111 

22222222222222 

33333333333333 

44444444444444 

55555555555555 

$ sed = foo | sed 'N;s/\n/   /' 
1       11111111111111 
2       22222222222222 
3       33333333333333 
4       44444444444444 
5       55555555555555 

解释: 
N 的作用是加上行号,可以用于格式化输出文件 


例子五 
sed '1!G;h;$!d' 
sed -n '1!G;h;$p' 
将文件的行反序显示,相当于 tac 命令(有些平台没有这个命令) 

代码:

$ cat foo 
11111111111111 
22222222222222 
33333333333333 

$ sed '1!G;h;$!d' foo 
33333333333333 
22222222222222 
11111111111111 

$ sed -n '1!G;h;$p' foo 
33333333333333 
22222222222222 
11111111111111 


解释: 
sed 中 h 用法:h 
The h (hold) function copies the contents of the pattern space into a holding area, destroying any previous contents of the holding area. 
意思是将模式空间的内容保存到保持空间中去 

sed 中的 d 表示删除模式空间。 

1!G表示除了第一行以外,其余行都执行G命令;$!d表示除了最后一行以外,其余行都执行d命令。 

看一下sed '1!G;h;$!d'命令执行过程中保持空间与模式空间的变化: 

命令 保持空间 模式空间 
第一行 h;d 执行前:null 执行后:1111\n 执行前:1111\n 执行后:null 
第二行 G;h;d 执行前:1111 执行后:2222\n1111\n 执行前:2222\n 执行后:null 
第二行 G;h 执行前:2222\1111\n 执行后:3333\n2222\n\1111\n 执行前:3333\n 执行后:3333\n2222\n\1111\n 

(注:把各个行简写了) 

这样输出以后就是文件的反序了。 

题外话:在vi中对一个文件进行反序显示的命令是 :g/./m0 , 意思是按照文件正常顺序每找到一行,就把该行放到文件的最上面一行去,这样循环一下正好把文件的行反序显示了。 

阅读原文

转载于:https://www.cnblogs.com/276815076/p/7879666.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/281813.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

dotnet 用 SourceGenerator 源代码生成技术实现中文编程语言

相信有很多伙伴都很喜欢自己造编程语言,在有现代的很多工具链的帮助下,实现一门编程语言,似乎已不是一件十分困难的事情。我利用 SourceGenerator 源代码生成技术实现了一个简易的中文编程语言,核心原理是将中文编程语言翻译为 C#…

断电后supervisor启动时报错

当设备意外断电后,supervisor在系统启动时报错,导致程序假死,此问题可以用systemd来替换supervisor。转载于:https://www.cnblogs.com/gaoyiping/p/6950470.html

Vue单页面在ios10系统上出现白屏的bug

一个bug 你用Vue做了一个单页面应用,它在一切设备上都工作正常,但是突然有一天,你的测试和你说,这个网站在iOS 10上跑不起来,怎么办?于是你打开你电脑上的Chrome浏览器,工作正常;打开…

HTTP/2 规格制定完成

IETF HTTP工作者的负责人Mark Nottingham在其博客上宣布HTTP/2规格制定完成,接下来将是分配RFC编号和正式发表。HTTP是Web的核心技术之一,相比HTTP/1,HTTP/2的改进之处包括更快的页面加载;更长久的连接;服务器推送&…

【习题 6-7 UVA - 804】Petri Net Simulation

【链接】 我是链接,点我呀:) 【题意】 在这里输入题意 【题解】 模拟就好 【代码】 /* 1.Shoud it use long long ? 2.Have you ever test several sample(at least therr) yourself? 3.Can you promise that the solution is right? At least,the main ideal 4.use the p…

easyui combobox java_Easyui的combobox实现动态数据级联效果

实现从数据库中动态获取对应的list集合,并在easyui的combobox中显示出来。实现的效果如下:1、数据库的表设计如图所示2、数据库中填写相关的数据,如图所示。如图所示【法律法规】是所属栏目,因此他的字段parentid是0。【中国公民出…

为什么应该默认将 Class 设为密封类?

前言最近在 dotnet/sdk 上看到一个 Issue,它提出了一个有趣的要求:默认情况下将类设置为密封类(Sealed)?什么是密封类?默认情况下,类是开放的,这意味着它是可以被继承的。例如:class BaseClass …

Spring工具类的使用

2019独角兽企业重金招聘Python工程师标准>>> Spring-core中提供了大量的工具类,常用的有StringUtils、ObjectUtils、NumberUtils、Base64Utils等,Spring工具类在spring-core.jar中的org.springframework.util包下。 org.springframework.util…

python作业高级FTP(第八周)

作业需求: 1. 用户加密认证 2. 多用户同时登陆 3. 每个用户有自己的家目录且只能访问自己的家目录 4. 对用户进行磁盘配额、不同用户配额可不同 5. 用户可以登陆server后,可切换目录 6. 查看当前目录下文件 7. 上传下载文件,保证文件一致性 8…

java用log.i打印数组_java-使用JSCH将ssh日志打印到列表(android)

我一直试图通过将包含我目录名称的log.i字符串值添加到数组中,然后使用数组适配器通过listView打印它们,来在listView中的目录中打印项目.但是,当我尝试运行该应用程序时,它将打印包含目录名称的日志,但不会在listView上打印任何内容.有什么帮助吗?这是我的代码&…

Edge 浏览器被爆存在 XSS 绕过漏洞

来自知名安全测试套件Burp Suite厂商PortSwigger的安全专家Gareth Heyes近日在微软Edge浏览器的内置XSS过滤器存在绕过漏洞,这就意味着尽管微软在Edge浏览器中进行了大量的安全策略部署,但用户浏览网页的时候依然有可能让攻击者通过这种方式在Edge浏览器…

来了!十大更新

面向 Windows 10 正式版用户,微软发布了 2022 年 10 月更新。Windows 10 版本 21H1 更新后操作系统内部版本升级至 Build 190432130/2132(带外更新)。Windows 10 版本 21H2 更新后操作系统内部版本升级至 Build 19044.2130/2132(带…

使用ansible 批量分发SSH Key

先确保你电脑有ansible,我是mac的用brew安装,其他可用yum安装brew search ansiblebrew install ansible我已经安装好2.7了生成下自己的key,一路回车ssh-keygen -t rsa编辑host,添加需要增加ssh key的机器vi /etc/ansible/hosts【hostgroup】我…

使用Git简单笔记

这里只是作为简单的笔记整理,第一次使用的推荐先看一下廖大的教程,内容很多很细,可以边看边练、看不懂的地方先记着、争取七七八八看下来。 心情不佳的分割线 廖雪峰的git教程: https://www.liaoxuefeng.com/wiki/001373951630592…

java中的path类_详谈java中File类getPath()、getAbsolutePath()、getCanonical的区别

简单看一下描述,例子最重要。1、getPath():返回定义时的路径,(就是你写什么路径,他就返回什么路径)2、getAbsolutePath():返回绝对路径,但不会处理“.”和“..”的情况3、getCanonicalPath():返…

部署站点支持Https访问的方法

1、申请公钥和私钥,放到服务器 2、编辑default配置文件 改为 加上证书路径 ps:泛域名支持admin.xxx.com、demo.xxx.com等等,而免费的Lets Encrypt仅支持www.xxx.com和xxx.com 整理自www.laravist.com转载于:https://www.cnblogs.com/lamp01/p/6952464.ht…

.NET Core Onvif协议C#教程系列之XiaoFeng.Onvif组件库

物联网IOT大背景下音视频领域的Onvif 协议在2008年成为全球性的开放接口标准。于是一批开发者涌入该技术领域使用各种编程语言对其改造升级封装。因为是国际标准,所以规范内容比较多,物联网领域涉及又广,所以研究协议是一个很耗时间的一项工作…

php异常处理的深入

引出 如果你调一个类,调用时数据验证时报了个错,你会以什么方式返回 数组,布尔值? 数组这个可以带错误原因回来,那布尔值呢? 返回了个 false, 报错时把错误放在类变量里?还是专门用一个获取错误…

C# 跨平台的支付类库ICanPay

随着微软的开源,越来越多的项目支持跨平台,但是各种支付平台提供的类库,又老又不支持跨平台,吐槽下,尤其是微信,还有好多坑,于是ICanPay诞生了,今天就来讲ICanPay是什么,…

.NET CORE 下收发邮件之 MAILKIT

背景利用代码发送邮件在工作中还是比较常见的,相信大家都用过SmtpClient来处理发送邮件的操作,不过这个类以及被标记已过时,所以介绍一个微软推荐的库MailKit来处理。MailKit开源地址:https://github.com/jstedfast/MailKit需要邮…