全部博文(470)
分类:
2010-03-10 12:29:43
sed大写的P命令和D命令的用法我不明白。看了man,上面写: D Deletes the initial segment of the pattern space through the first newline and starts the next cycle. P Prints (copies) the initial segment of the pattern space through the first newline to the standard output. 但是里面那句through the first newline 看不懂,是什么意思?newline指的是什么?还有initial segment 指的又是什么?谁能结合一些例子讲解一下? 回复于:2004-03-18 17:30:32 这帖子沉到底了。顶上来。 请sed达人就以下例子为我解释一下: 引用: 6.按关键字拼接行 如果某行以=开始,则合并到上一行并替代=为空格 代码: sed -e :a -e '$!N;s/\n=/ /;ta' -e 'P;D' 举例 代码: cat file 111111111111111111 222222222222222222 =333333333333333333 444444444444444444 sed -e :a -e '$!N;s/\n=/ /;ta' -e 'P;D' filename 111111111111111111 222222222222222222 333333333333333333 444444444444444444 如果不加-e'P;D',那么后面的以“=”号开头的行都不会合并上来,可是我不理解-e'P;D'的意思,请高手解释一下。 回复于:2004-03-18 17:40:36 见ad版主的sed学习日记: 回复于:2004-03-18 18:11:21 我这个例子就是从那篇帖子里面抄的呀,但是这个例子还是没有看懂。能不能结合这个例子解释一下? 回复于:2004-03-18 18:55:09 我来试着解释一下,如有不妥,请见谅。 -e :a 定义一个标签位置 $!N 如果不是最后一行,就读入新行附加于pattern space之后,以“\n”分隔 s/\n=/ / 如果发现了新行是以=开头的,替换为空格 ta 如果找到了替换,从标签a处再执行,否则向下走 P 打印 pattern space中的第一个 \n之前的内容 D 删除pattern space中的第一个 \n之前的内容,并返回脚本头部执行 各个命令解释清楚了,再看执行过程: 第一行执行,没有找到 \n= 打印第一行,读入第二行,脚本头部执行 第二行执行,找到 \n= ,替换为空格,从标签a处再执行 第三行执行,没有找到 \n= 打印第二三行的合并和第四行,读入新行,没有了,结束。 我非常敬仰admirer,如有不对,请指正。 回复于:2004-03-19 09:52:54 引用: -e :a 定义一个标签位置 理解 引用: $!N 如果不是最后一行,就读入新行附加于pattern space之后,以“\n”分隔 理解 引用: s/\n=/ / 如果发现了新行是以=开头的,替换为空格 理解 引用: ta 如果找到了替换,从标签a处再执行,否则向下走 不理解,这条命令有分条件执行吗?为什么说“如果找到替换再到a执行”,s命令后不是都要执行ta这条命令吗,哪个命令指定这条ta是根据s的结果来处理的? 引用: P 打印 pattern space中的第一个 \n之前的内容 D 删除pattern space中的第一个 \n之前的内容,并返回脚本头部执行 理解 引用: 第一行执行,没有找到 \n= 打印第一行,读入第二行,脚本头部执行 是不是先定义标号a,然后N读入下一行,然后执行s替换,因为没有找到替换,所以不执行ta?然后打印模式空间中\n前面内容,就是第一行,再删除模式空间\n前面内容即第一行,保留第二行。 引用: 第二行执行,找到 \n= ,替换为空格,从标签a处再执行 第三行执行,没有找到 \n= 打印第二三行的合并和第四行,读入新行,没有了,结束。 此时模式空间里面是第二行。先定义标号a,然后N读入下一行(第三行),然后执行s替换,这时\n就没有了,模式空间是2、3行的合并,然后ta,再N读入下一行(第四行),然后执行s替换,因为没有找到替换,所以不执行ta,然后打印模式空间中\n前面内容,就是二、三行的合并,删除后保留第四行。 这时再执行sed,定义标号a,发现是最后一行,所以N,s,t三个命令都不执行,执行P;D命令,打印第四行,再删除模式空间的内容。 我的理解对吗? 问题:N命令是由前面的$!决定是否执行的,这个我理解。s命令的执行条件是什么?是不是前面的N执行成功s才执行?t命令的执行条件是不是s命令成功才执行?-e :a和-e'P;D'是不是不管什么条件都执行? 请大虾赐教! 回复于:2004-03-19 10:24:09 我的第三行执行写的不清楚,图了省事,你的理解很不错,但也有点问题。 就是这个 -e:a有点问题,我不知道自己理解的是否对,我认为这个标签只定义一次。不是每一行都定义的。还有这个ta 他就相当于if found 替换 goto a; s命令的执行无条件,有就替换,没有就不替换;'P;D'是不管什么条件都执行。 欢迎交流。 回复于:2004-03-19 10:46:34 我是觉得sed的每一个命令地位都是相等的,所以我认为-e :a是每读入一行的时候都执行一次。 还有如果s命令没有条件的话,那么t命令为什么就是“if found 替换”才能跳到a呢?s命令为什么不是“if found 替换”再执行替换呢?我觉得s命令和t命令的执行顺序是按顺序执行的,所以如果s命令有执行,t命令也要执行。如果s命令没有执行(当然不考虑s匹配不到自己的正则表达式的情况),那么t命令也不会执行。对吗? 我现在P命令和D命令已经搞明白了,但是命令组合中的命令执行顺序和执行条件越搞越不明白。比如下列几种情况: sed -e 'comd1' -e 'comd2' sed -e 'comd1;comd2' sed -e '$!comd1;comd2' sed -e '/reg/{comd1;comd2;}' 不知道还有没有其他组合,这几个有什么不同吗? 回复于:2004-03-19 11:46:47 COMM:代表命令,PATT:代表pattern space的内容,其他为sed输出的内容 PATT:111111111111111111$ 回复于:2004-03-19 15:23:52 看了版主的解释,应该“:a”命令和“ta”命令都是每次读入一行后都要执行的,我的理解对吗?那么仍然有一个疑问:执行了命令t a以后,为什么有时候是执行P命令,有时候是执行$!N命令?这个跳转命令的条件是什么呢? 回复于:2004-03-19 15:26:16 请参考一下 t label 回复于:2004-03-19 16:03:39 看上面这段英文解释,t命令在读入一行或者上次t命令后如果有个s命令执行成功,那么t命令就跳转,否则不跳转,这个解释和我系统上面的man基本一样。 用这个解释来说明版主上面的流程,我想我是懂了。但是我自己设计了一个例子,运行结果又让我糊涂了,所以我可能不是真懂。 例子是这样的:
运行命令
运行命令
后者的执行结果我无论如何没法理解。 我先说一下我对后者的理解: 读入第一行aaa,执行N读入第二行bbb,执行s替换,没有成功,不执行ta,打印模式空间,内容是aaa\nbbb 读入第三行ccc,执行N读入第四行ddd,执行s替换成功,模式空间是111\nddd,执行ta,再执行N读入第五行,模式空间是111\nddd\neee,执行s替换不成功,我认为此时ta应该不执行,结束命令打印模式空间111\nddd\neee,可是为什么没有? 然后应该读入第六行……,最后结果应该和前者一样,可是为什么打印到bbb这行就嘎然而止了? 希望版主和诸位大虾不要被我的无知和罗嗦吓跑,发扬耐心的传帮带的风格,谢谢。 回复于:2004-03-19 16:17:01 呵呵,搂主很认真啊,这挺好的,不用怕麻烦。 你试着将你的文件改一下,改为如下: aaa 就会发现,sed -e :a -e'N;s/c/1/;ta' file 输出的又有了。 我就不解释了,自己思考一下吧。 回复于:2004-03-19 16:18:48 哦,我明白了,因为我刚才在我的例子里面发现了一个问题: sed -e :a -e'N;s/c/1/;ta' eee 在s命令里面没有指明替换第几个,所以缺省只替换了第一个,那么在N读入第四行时, PATT=ccccc\nddd s命令之后, PATT=1cccc\nddd ta命令之后,N读入第五行, PATT=1cccc\nddd\neee s命令之后, PATT=11ccc\nddd\neee 所以ta命令继续跳转,再读入第六行, PATT=11ccc\nddd\neee\nfff s命令之后, PATT=111cc\nddd\neee\nfff …… …… 所以文件读完后,因为s命令一直成功,t命令仍要执行,所以循环还没有结束,模式空间就不打出来了。如果把第三行少写几个“c”,或者eee文件多写几行,最后就可以打印出全部替换过的文件了。 实践+思考+他人帮助是成功掌握一门知识的不二法门哪。 回复于:2004-03-19 16:24:35 引用:原帖由 "forest077"]看了版主的解释,应该“:a”命令和“ta”命令都是每次读入一行后都要执行的, 发表: 请看b[label]的用法说明: The label is optional, and if not supplied, control is transferred to the end of the script. If alabel is supplied, execution resumes at the line following the label. 回复于:2004-03-19 16:24:50 发完帖子看到skydog兄的回帖,我想我的思考是对的了,但是skydog举的例子有一个问题,“ccc……”那一行的字符个数如果是4个仍然不能打印出来,如果改成3个或以下才能打印出下面几行的内容。 回复于:2004-03-19 16:35:54 呵呵,我拷贝你的文件,文件末尾多了一个空行,所以4个正好能打印出来,我试了的。 另请注意我之前的关于b[label]的说明。 回复于:2004-03-19 17:12:59 b和t命令的区别是不是前者是无条件跳转,后者是s命令成功后才跳转? 为什么要我注意b命令的说明,和我举的例子有什么关系吗? |
原文链接: 转载请注明作者名及原文出处 |
感谢所有关心和支持过ChinaUnix的朋友们