免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3061 | 回复: 13

[文本处理] 一个sed命令的执行过程,求大神指点 [复制链接]

论坛徽章:
0
发表于 2015-04-11 14:02 |显示全部楼层
本帖最后由 cpy9981 于 2015-04-11 14:04 编辑

问题有点繁琐,希望大神帮忙指点,

测试文本file:
John Doe
CEO @Chief Executive Officer@
Jason Smith
IT Manager @Information Technology
Officer@
Raj Reddy
Sysadmin @System Administrator@
Anand Ram
Developer @Senior
Programmer@
Jane Miller
Sales Manager @Sales
Manager@


测试目标是,去除所以 @ 之间的注释    @.*@

sed -e '/@/{N;/@.*@/{s/@.*@//; P;D}}' file

输出结果是:
John Doe
CEO
Jason Smith
IT Manager
Raj Reddy
Sysadmin
Anand Ram
Developer
Jane Miller
Sales Manager


不理解的地方有好几处,写得有点繁琐,希望大神帮忙指点,

1,sed处理每行的时候,里面的运行过程到底是什么样的?
    首先,把要处理的行,读取到模式空间,再执行后面的命令。
    当/@/  匹配到某行时,例如:CEO @Chief Executive Officer@,
    在模式空间里,会再生成一个新行么? 也就是说,模式空间里面,这个时候有两行 CEO @Chief Executive Officer@     是不是 ?????
   
2,然后N命令,把下一行追加到模式空间里面,此时的模式空间,是不是有以下三行 ?????
     CEO @Chief Executive Officer@       # 这行是sed默认读取行到模式空间???
     CEO @Chief Executive Officer@       # 这是/@/ 匹配到的行
     Officer@                                       # 这是N命令追加的。

3,然后 /@.*@/ 匹配到当前模式空间有匹配的内容, 再执行 s/@.*@//  把注释替换掉。

3,P 打印第一行 ,即 CEO

4,D 删除第一行,


根据,输出结果,我的理解过程明显不对,很迷乱,望大神不吝指点!跪谢



论坛徽章:
28
2015年迎新春徽章
日期:2015-03-04 10:16:53午马
日期:2015-03-20 17:11:07亥猪
日期:2015-03-20 17:11:23戌狗
日期:2015-03-20 17:11:33酉鸡
日期:2015-03-20 17:11:47申猴
日期:2015-03-20 17:11:58未羊
日期:2015-03-20 17:12:10子鼠
日期:2015-03-20 17:12:23丑牛
日期:2015-03-20 17:12:40卯兔
日期:2015-03-20 17:12:51辰龙
日期:2015-03-20 17:13:00巳蛇
日期:2015-03-20 17:13:12
发表于 2015-04-11 14:13 |显示全部楼层
  1. sed -r ':1;N;$!b1;s/@[^@]+@//g' inputfile
复制代码

论坛徽章:
28
2015年迎新春徽章
日期:2015-03-04 10:16:53午马
日期:2015-03-20 17:11:07亥猪
日期:2015-03-20 17:11:23戌狗
日期:2015-03-20 17:11:33酉鸡
日期:2015-03-20 17:11:47申猴
日期:2015-03-20 17:11:58未羊
日期:2015-03-20 17:12:10子鼠
日期:2015-03-20 17:12:23丑牛
日期:2015-03-20 17:12:40卯兔
日期:2015-03-20 17:12:51辰龙
日期:2015-03-20 17:13:00巳蛇
日期:2015-03-20 17:13:12
发表于 2015-04-11 14:21 |显示全部楼层
1,不是
2,匹配到
  1. CEO @Chief Executive Officer@
复制代码
这一样的时候,执行N
这时候模式空间里是
  1. CEO @Chief Executive Officer@
  2. Jason Smith
复制代码
3.
  1. .*
复制代码
是贪婪匹配,匹配到
  1. CEO @Chief Executive Officer@
复制代码
这行的时候,执行N,如果下一行仍旧含有@字符.那么你的替换就有问题了,好在你给的文本中没有这种情况~
4.P和D就是你理解的意思

求职 : 机器学习
论坛徽章:
79
2015年亚洲杯纪念徽章
日期:2015-05-06 19:18:572015七夕节徽章
日期:2015-08-21 11:06:172015亚冠之阿尔纳斯尔
日期:2015-09-07 09:30:232015亚冠之萨济拖拉机
日期:2015-10-21 08:26:3915-16赛季CBA联赛之浙江
日期:2015-12-30 09:59:1815-16赛季CBA联赛之浙江
日期:2016-01-10 12:35:21技术图书徽章
日期:2016-01-15 11:07:2015-16赛季CBA联赛之新疆
日期:2016-02-24 13:46:0215-16赛季CBA联赛之吉林
日期:2016-06-26 01:07:172015-2016NBA季后赛纪念章
日期:2016-06-28 17:44:45黑曼巴
日期:2016-06-28 17:44:4515-16赛季CBA联赛之浙江
日期:2017-07-18 13:41:54
发表于 2015-04-11 15:36 |显示全部楼层
《sed and awk 101 hacks》好书啊

论坛徽章:
0
发表于 2015-04-14 22:10 |显示全部楼层
回复 2# 我是一隻羊

谢谢你的解答,
我大概明白了D的运行原理。如果当前模式空间有多行,D删除第一行之后,sed不会读取下一行,而是继续从命令起始开始执行,正如文档里面说的那样:If  pattern  space contains no newline, start a normal new cycle as if the d command was issued.  Otherwise, delete text in the pattern space up to the first newline, and restart cycle with the resultant pattern space, without reading a new line of input.


对于你的这串处理命令。我有一个疑问:
:1;N;$!b1;    这一串命令,是不是把文件中的所有行,都通过N命令,追加到了当前模式空间。{ 分支命令b 的含义,是不是说,只有不是行尾($!) 就继续跳到标签1,继续执行N. }

然后执行 s/@[^@]+@//g   把所有@...@  都替换掉?

   

论坛徽章:
0
发表于 2015-04-14 22:10 |显示全部楼层
回复 4# zsszss0000

正是


   

论坛徽章:
28
2015年迎新春徽章
日期:2015-03-04 10:16:53午马
日期:2015-03-20 17:11:07亥猪
日期:2015-03-20 17:11:23戌狗
日期:2015-03-20 17:11:33酉鸡
日期:2015-03-20 17:11:47申猴
日期:2015-03-20 17:11:58未羊
日期:2015-03-20 17:12:10子鼠
日期:2015-03-20 17:12:23丑牛
日期:2015-03-20 17:12:40卯兔
日期:2015-03-20 17:12:51辰龙
日期:2015-03-20 17:13:00巳蛇
日期:2015-03-20 17:13:12
发表于 2015-04-14 22:11 |显示全部楼层
回复 5# cpy9981


    对,就是这个意思~

论坛徽章:
0
发表于 2015-04-14 22:24 |显示全部楼层
本帖最后由 cpy9981 于 2015-04-14 22:25 编辑

回复 7# 我是一隻羊

谢谢哈
:1;N;$!b1;  相当于是一个循环,只要不是行尾,就继续N命令追加下一行。

但是,

N命令,把下一行追加到当前模式空间时,仍然是分行的,即带一个\n 换行,并不是追加在一行里面。

那么这个 $!  具体该怎么解释呢?

虽然N命令把文件里面所有行都追加到了当前模式空间,但是每一行尾,不都有一个$ 么?  恕我愚钝。这个地方,还是有一点疑惑

   

论坛徽章:
0
发表于 2015-04-14 22:33 |显示全部楼层
回复 4# zsszss0000

这本书似乎并没有涵盖sed文档里面,所有的内容。不过通过学习这本书,再去看sed官方文档,倒是顺畅多啦


   

论坛徽章:
28
2015年迎新春徽章
日期:2015-03-04 10:16:53午马
日期:2015-03-20 17:11:07亥猪
日期:2015-03-20 17:11:23戌狗
日期:2015-03-20 17:11:33酉鸡
日期:2015-03-20 17:11:47申猴
日期:2015-03-20 17:11:58未羊
日期:2015-03-20 17:12:10子鼠
日期:2015-03-20 17:12:23丑牛
日期:2015-03-20 17:12:40卯兔
日期:2015-03-20 17:12:51辰龙
日期:2015-03-20 17:13:00巳蛇
日期:2015-03-20 17:13:12
发表于 2015-04-14 22:35 |显示全部楼层
回复 8# cpy9981


这里的$不是pattern而是address
指的是文件最后一行
比如
  1. sed -n '3,$p' inputfile
复制代码
这里的$就是address,指的是文件最后一行
再比如
  1. sed -n '3,$s/$/test/p' inputfile
复制代码
这里的第二个$才是pattern,匹配模式空间的末尾位置.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP