免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 10966 | 回复: 22
打印 上一主题 下一主题

通过几个例子看sed的模式空间与保持空间  关闭 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2003-09-08 11:19 |只看该作者 |倒序浏览
近来看到几个不是很常见,但是比较有用的sed例子,都和hold space与pattern space有关,于是对几个例子做了自己认为正确的解释,贴出来与大家共享并请指正,继续讨论

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


  1. $ cat foo
  2. 11111111111111
  3. 22222222222222
  4. 33333333333333
  5. 44444444444444
  6. 55555555555555

  7. $ sed G foo
  8. 11111111111111

  9. 22222222222222

  10. 33333333333333

  11. 44444444444444

  12. 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'
在文件的每一个非空行下面输出两个空行


  1. $ cat foo
  2. 11111111111111
  3. 22222222222222

  4. 33333333333333
  5. 44444444444444
  6. 55555555555555

  7. $ sed '/^$/d;G' foo
  8. 11111111111111

  9. 22222222222222

  10. 33333333333333

  11. 44444444444444

  12. 55555555555555

复制代码


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


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

  1. $ cat foo
  2. 11111111111111
  3. 22222222222222
  4. test33333333333333
  5. 44444444444444
  6. 55555555555555

  7. $ sed '/test/{x;p;x;}' foo
  8. 11111111111111
  9. 22222222222222

  10. test33333333333333
  11. 44444444444444
  12. 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;'
在文件的偶数行下面插入一个空行

  1. $ cat foo
  2. 11111111111111
  3. 22222222222222
  4. 33333333333333
  5. 44444444444444
  6. 55555555555555

  7. $ sed 'n;G;' foo
  8. 11111111111111
  9. 22222222222222

  10. 33333333333333
  11. 44444444444444

  12. 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


  1. $ cat foo
  2. 11111111111111
  3. 22222222222222
  4. 33333333333333
  5. 44444444444444
  6. 55555555555555

  7. $ sed '$!N;$!D' foo
  8. 44444444444444
  9. 55555555555555

复制代码


解释:

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

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


还有 N 的另外一种用法

  1. $ sed = foo | sed N
  2. 1
  3. 11111111111111
  4. 2
  5. 22222222222222
  6. 3
  7. 33333333333333
  8. 4
  9. 44444444444444
  10. 5
  11. 55555555555555

  12. $ sed = foo | sed 'N;s/\n/        /'
  13. 1       11111111111111
  14. 2       22222222222222
  15. 3       33333333333333
  16. 4       44444444444444
  17. 5       55555555555555
复制代码

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


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


  1. $ cat foo
  2. 11111111111111
  3. 22222222222222
  4. 33333333333333

  5. $ sed '1!G;h;$!d' foo
  6. 33333333333333
  7. 22222222222222
  8. 11111111111111

  9. $ sed -n '1!G;h;$p' foo
  10. 33333333333333
  11. 22222222222222
  12. 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 , 意思是按照文件正常顺序每找到一行,就把该行放到文件的最上面一行去,这样循环一下正好把文件的行反序显示了。


这只是自己对模式空间与保持空间的一点点理解,个人觉得在这个方面还有很多东西要学,请大家拍砖。

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
2 [报告]
发表于 2003-09-08 11:34 |只看该作者

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

50.gif (1.1 KB, 下载次数: 126)

50.gif

15.gif (15.69 KB, 下载次数: 89)

15.gif

论坛徽章:
0
3 [报告]
发表于 2003-09-08 11:48 |只看该作者

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

学习中,支持

论坛徽章:
0
4 [报告]
发表于 2003-09-08 12:11 |只看该作者

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

mark

论坛徽章:
0
5 [报告]
发表于 2003-09-08 12:23 |只看该作者

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

论坛徽章:
0
6 [报告]
发表于 2003-09-08 12:58 |只看该作者

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

我 收藏先 。。。。。。

论坛徽章:
0
7 [报告]
发表于 2003-09-08 13:00 |只看该作者

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

看unix shell的书里有对sed的详细介绍,不过当看什么交换,什么模式空间保持空间的那段时,我头都大啦~~~好烦的!

论坛徽章:
0
8 [报告]
发表于 2003-09-08 13:15 |只看该作者

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

其实就这几个例子,昨天就把自己关在宿舍里想了一天,确实很烦

不过也是出于对这些sed代码的好奇,想知道这些简洁代码背后的原理,才想去写几句。

论坛徽章:
0
9 [报告]
发表于 2003-09-08 15:00 |只看该作者

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

逐字逐句地看完这个帖子以后,我的心久久不能平静,震撼啊!为什么会有如此好的帖子?!我纵横网络BBS多年,自以为再也不会有任何帖子能打动我,没想到今天看到了如此精妙绝伦的这样一篇帖子。

论坛徽章:
0
10 [报告]
发表于 2003-09-08 15:21 |只看该作者

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

[quote]原帖由 "夜未眠"]逐字逐句地看完这个帖子以后,我的心久久不能平静,震撼啊!为什么会有如此好的帖子?!我纵横网络BBS多年,自以为再也不会有任何帖子能打动我,没想到今天看到了如此精妙绝伦的这样一篇帖子。[/quote 发表:
     
我的牙~~~在哪儿~~~????
(呕吐ing...)
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP