sed 模式空间 保持空间

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

正常情况下,如果不显示使用某些高级命令,保持空间不会使用到!

sed在正常情况下,将处理的行读入模式空间,脚本中的“sed command(sed命令)”就一条接着一条进行处理,直到脚本执行完毕。然后该行被输出,模式空间被清空;接着,在重复执行刚才的动作,文件中的新的一行被读入,直到文件处理完毕。

一般情况下,数据的处理只使用模式空间(pattern space),按照如上的逻辑即可完成主要任务。但是某些时候,通过使用保持空间(hold space),还可以带来意想不到的效果。

命令含义:

h,将当前模式空间中的内容覆盖到 保持空间中,

n,用于提前读取下一行,并且覆盖当前模式空间中的这一行

H,将当前模式空间中的内容追加到 保持空间 中

x,交换模式空间和保持空间中的内容

g,将保持空间中的内容拷贝到模式空间中,原来模式空间里的内容清除。

d,删除模式空间中的所有行,并读入下一新行到模式空间中。
D,删除multiline pattern中的第一行,不读入下一行。

通过几个例子看sed的模式空间和保持空间
例子一
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‘ 对于KSH则为 sed ‘/^ *$/d‘

例子二
sed ‘/regex/{x;p;x;}‘
在匹配regex的任何行前面插入一个空行
代码:
$ cat foo
11111111111111
22222222222222
test33333333333
44444444444444
55555555555555

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

test33333333333
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 的作用是把模式空间复制到标准输出。
分析一下该命令执行过程中保持空间和模式空间的内容
命令 保持空间 (holdspace) 模式空间(patternspace)
x 执行前:null 执行后:test...$ 执行前:test...$ 执行后:null
p 执行前:null 执行后:test...$ 执行前:test...$ 执行后:null 输出一个空行
x 执行前:test...$ 执行后:null 执行前:null 执行后:test...$
个人觉得上面的命令执行分析有点问题,我的分析如下:
命令 模式空间(patternspace) 保持空间 (holdspace)
x 执行前:test...$ 执行后:null 执行前:null 执行后:test...$
p 执行前:null 执行后:null但输出一空行 执行前:test...$ 执行后:test...$
x 执行前:null 执行后:test...$ 执行前:test...$ 执行后:null
引申:能够试验一下 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是将模式空间的的第一行删除);(循环删除到模式空间里只剩下倒数第二行时)到倒数第二行的时候,将最后一行附加到倒数第二行下面,然后最后一行不执行 D ,所以文档的最后两行都保存下来了。
更有 N 的另外一种用法代码:
$ sed = foo | sed N (一定要这样的命令格式)
1
11111111111111
2
22222222222222
3
33333333333333
4
44444444444444
5
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 执行后:11..$ 执行前:11..$ 执行后:null
第二行 G;h;d 执行前:11..$ 执行后:22..$/n11..$ 执行前:22..$ 执行后:null
第二行 G;h 执行前:22..$/n11..$执行后:33..$/n22..$/n11..$ 执行前:33..$ 执行后:33..$/n22..$/n11..$
这样输出以后就是文档的反序了。

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

参考http://www.xuebuyuan.com/951950.html

http://blog.csdn.net/wanglelelihuanhuan/article/details/51591809

原文地址:https://www.cnblogs.com/fanren224/p/8476603.html

时间: 2024-08-11 21:55:52

sed 模式空间 保持空间的相关文章

sed模式空间和暂存空间的区别

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

sed 之 模式空间 & 保持空间

模式空间:容纳当前输入行的缓冲区: 保持空间:作为辅助的一个缓冲区,可以和模式空间进行交互,但是命令不能直接作用于保持空间. 由上面定义可以知道,模式空间和保持空间是两个独立的缓冲区,可以进行交互,命令可以寻址模式空间但是不能寻址保持空间. 一.模式空间: 通过模式匹配到的行被读入模式空间中.用来进行进一步的操作:在多行模式中,'\n'可以用来和模式空间(N命令的结果)的任意换行符匹配,单模式空间底部的换行符除外.^匹配多行的首,$匹配多行的尾,不是每行的行首和行尾. 二.保持空间: 可以通过h

windbg 如何再内核模式调试用户空间的程序

1:使用!process 0 0 获取用户空间的所有的进程的信息 !process 0 0 **** NT ACTIVE PROCESS DUMP ****    PROCESS 80a02a60  Cid: 0002    Peb: 00000000  ParentCid: 0000    DirBase: 00006e05  ObjectTable: 80a03788  TableSize: 150.    Image: System ..... 2:使用.process /p + 你需要断

初学JAVA——栈空间堆空间的理解

1.Person pangzi;    //这是在“开拓空间”于栈空间 pangzi=new Person();    //这是赋值于堆空间 上两步就是在做与空间对应的事. 2.值类型直接存入栈空间,如AF,引用类型存入堆空间,在栈空间存有“索引地址”,如当需要B时,在栈空间寻找“索引地址”后对应寻找堆空间的“详细内容”. 故,值类型“快”,引用类型“灵活”. 例String S = “ABCDEFG........Z",则S对应栈空间,“ABCDEFG........Z"对应堆空间.

用户空间&内核空间学习 & top命令 & time命令

参考了这篇文章 http://www.ruanyifeng.com/blog/2016/12/user_space_vs_kernel_space.html 简单说,Kernel space 是 Linux 内核的运行空间,User space 是用户程序的运行空间. 为了安全,它们是隔离的,即使用户的程序崩溃了,内核也不受影响. Kernel space 可以执行任意命令,调用系统的一切资源: User space 只能执行简单的运算,不能直接调用系统资源,必须通过系统接口(又称 system

堆空间 栈空间

一个由C/C++编译的程序占用的内存分为以下几个部分:1.栈区(stack):又编译器自动分配释放,存放函数的参数值,局部变量的值等,其操作方式类似于数据结构的栈.2.堆区(heap):一般是由程序员分配释放,若程序员不释放的话,程序结束时可能由OS回收,值得注意的是他与数据结构的堆是两回事,分配方式倒是类似于数据结构的链表.3.全局区(static):也叫静态数据内存空间,存储全局变量和静态变量,全局变量和静态变量的存储是放一块的,初始化的全局变量和静态变量放一块区域,没有初始化的在相邻的另一

程序的内存空间 堆空间和栈空间的区别

一个由C/C++编译的程序占用的内存分为以下几个部分: 1.栈区(stack): 由编译器自动分配释放,其操作方式类似于数据结构的栈. 用于存放函数的参数值,用户程序临时创建的局部变量等,即函数括号"{}"中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量).除此之外,在函数被调用时,其参数也会被压入发起调用的进程栈中,等到调用结束后,函数的返回值也会被存放回栈中. 由于栈的后进先出特点,所以栈特别方便用来保存/恢复调用现场.从这个意义上讲,可以把栈看成

数学空间/希尔伯特空间

想要理解数学空间和希尔伯特空间,我们的思路是: 现代数学-->集合-->线性空间(向量空间)及基的概念-->赋范空间-->內积空间-->希尔伯特空间 于是,我们想要理解希尔伯特空间,首先需要从距离开始,然后说说线性空间,到范数空间,再到內积空间,最后一直到欧式空间,希尔伯特空间和巴拿赫空间. 现代数学最大的特点就是以集合为研究对象,将不同问题的本质抽取出来,变成同一类问题.而集合分为两种:有线性结构的集合(线性空间/向量空间):以及有度量结构的集合(度量空间).要说欧式空间和

python 2018.7.24 类空间,对象空间,查询顺序 ,组合

查询顺序: 对象.属性 : 先从对象空间找,如果找不到,再从类空间找,再找不到,再从父类找.... 类名.属性 : 先从本类空间找,如果找不到,再从父类找.... 对象与对象之间是互相独立的. 计算一个类 实例化多少对象.例 class Count: count = 0 def __init__(self): Count.count = self.count + 1 obj1 = Count() obj2 = Count() print(Count.count) count = 0 class