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 , 意思是按照文件正常顺序每找到一行,就把该行放到文件的最上面一行去,这样循环一下正好把文件的行反序显示了。

阅读原文

通过几个例子看sed的模式空间与保持空间的更多相关文章

  1. 借个例子说明sed的模式空间,以及针对模式空间的N,P,D用法

    下面是我们要处理的文本:题目要求是把所有散列在不同行的同一个中括号中的数据集中在一起, 见下表就秒懂了吧 处理前的文本 处理后的文本 [123456][ASDEF][ABCD123WF][789ADC ...

  2. Spark小课堂Week7 从Spark中一个例子看面向对象设计

    Spark小课堂Week7 从Spark中一个例子看面向对象设计 今天我们讨论了个问题,来设计一个Spark中的常用功能. 功能描述:数据源是一切处理的源头,这次要实现下加载数据源的方法load() ...

  3. 结合JDK源码看设计模式——迭代器模式

    前言: Iterator翻译过来就是迭代器的意思.在前面的工厂模式中就介绍过了iterator,不过当时介绍的是方法,现在从Iterator接口的设计来看,似乎又是一种设计模式,下面我们就来讲讲迭代器 ...

  4. 结合JDK源码看设计模式——策略模式

    前言: 现在电商已经成为我们生活中不可或缺的购物渠道,同时各大商家会针对不同的时间做出不同的折扣,这在我们看来就是一种营销手段,也是一种策略,今天我们就来讲讲JDK中的策略模式是怎么样的. 一.定义 ...

  5. 转 从红帽、GitHub和Docker看开源商业模式的进阶

    从红帽.GitHub和Docker看开源商业模式的进阶 发表于2014-12-16 10:26| 7594次阅读| 来源http://stratechery.com/| 0 条评论| 作者Ben Th ...

  6. sed的模式空间和保持空间

    摘自:https://blog.csdn.net/wanglelelihuanhuan/article/details/51591809 sed的模式空间和保持空间 2016年06月06日 17:15 ...

  7. 用例子看ASP.NET Core Identity是什么?

    原文:用例子看ASP.NET Core Identity是什么? 目录 前言 基于声明的认证(Claims-based Authentication) Claim 在ASP.NET Core Iden ...

  8. sed 之 模式空间 & 保持空间

    模式空间:容纳当前输入行的缓冲区: 保持空间:作为辅助的一个缓冲区,可以和模式空间进行交互,但是命令不能直接作用于保持空间. 由上面定义可以知道,模式空间和保持空间是两个独立的缓冲区,可以进行交互,命 ...

  9. 结合JDK源码看设计模式——模板方法模式

    前言: 相信很多人都听过一个问题:把大象关进冰箱门,需要几步? 第一,把冰箱门打开:第二,把大象放进去:第三,把冰箱门关上.我们可以看见,这个问题的答案回答的很有步骤.接下来我们介绍一种设计模式--模 ...

随机推荐

  1. JS进阶之---作用域,作用域链,闭包

    一.作用域: 在JavaScript中,我们可以将作用域定义为一套规则,这套规则用来管理引擎如何在当前作用域以及嵌套的子作用域中根据标识符名称进行变量查找.这里的标识符,指的是变量名或者函数名. Ja ...

  2. HashMap的扩容机制---resize()

    虽然在hashmap的原理里面有这段,但是这个单独拿出来讲rehash或者resize()也是极好的. 什么时候扩容:当向容器添加元素的时候,会判断当前容器的元素个数,如果大于等于阈值---即当前数组 ...

  3. PAT A1144 The Missing Number (20 分)——set

    Given N integers, you are supposed to find the smallest positive integer that is NOT in the given li ...

  4. java 文件字节和字符流 缓冲流

    流的原理 1) 在 Java 程序中,对于数据的输入/输出操作以“流”(stream) 方式进行:2) J2SDK 提供了各种各样的“流”类,用以获取不同种类的数据:程序中通过标准的方法输入或输出数据 ...

  5. MVC 5限制所有HTTP请求必须是POST方式

    今天有位同事,提出了这样一个问题,他想限制所有MVC接收到的HTTP请求必须是POST方式. 接下来在下面的内容中,将我想到的方式分享给大家,如果大家有其它的方式,请留言. 一.HttpPostAtt ...

  6. C++模板的特化

    C++类模板的三种特化,讲得比较全面 By SmartPtr(http://www.cppblog.com/SmartPtr/) 针对一个模板参数的类模板特化的几种类型, 一是特化为绝对类型(全特化) ...

  7. Vue-使用json-server快速“伪造”后台接口

    JSON-Server主要的作用是搭建一台JSON服务器,测试一些业务逻辑(我之前都是采用读取文件的方式尴尬).一.安装 npm install --save json-server 前提是已经安装好 ...

  8. Ionic2 App Import BrowserAnimationsModule or NoopAnimationsModule问题

    在开发app的过程中遇见了动画相关方面的问题,具体如下: 解决方法是:在app.module.ts模块中引入BrowserAnimationsModule import { BrowserAnimat ...

  9. 51Nod 1443 路径和树

    还是一道很简单的基础题,就是一个最短路径树的类型题目 我们首先可以发现这棵树必定满足从1出发到其它点的距离都是原图中的最短路 换句话说,这棵树上的每一条边都是原图从1出发到其它点的最短路上的边 那么直 ...

  10. QZEZ第一届“饭吉圆”杯程序设计竞赛

    终于到了饭吉圆杯的开赛,这是EZ我参与的历史上第一场ACM赛制的题目然而没有罚时 不过题目很好,举办地也很成功,为法老点赞!!! 这次和翰爷,吴骏达 dalao,陈乐扬dalao组的队,因为我们有二个 ...