不会去到sed
的基础知识,这里是你的sed
命令细分:
$!N
:如果没有文件结尾,下一行追加到模式空间。这两行将被换行符分开(\n
)。在这个时候你的模式空间是201408\n201409
。
/^\(.*\)\n\1$/!P
:如果将模式空间不包含一个换行(\n
)分隔开的两个类似的内容,然后P
RINT直到第一换行符(\n
)。所以这将打印201408
到STDOUT。在第二次迭代期间,模式空间将有201409\n201409
,并且因为它失败正则表达式,没有打印,我们继续下一个命令。
D
:D
直到第一个换行符(\n
)并重复sed
脚本。重复周期中记住你的模式空间仍具有201409
所以在第一次迭代201408
期间被打印,但201409
没有得到打印,直到到达文件的结尾这是当你的正则表达式将再次成为真实,内容将被打印。
如果你继承了很多的sed
代码,我会强烈建议sedsed工具,它是写在python
,将帮助您了解错综复杂和晦涩sed
,往往可以成为一个维护的噩梦。 (我没有显示所有的迭代,因为它很详细,但你得到的图片。我已经添加了几个意见,什么输出真正的意思。还注意到我使用单一引号,因为我在Mac(BSD Unix等),而不是Windows)中:
$ sedsed.py -d '$!N; /^\(.*\)\n\1$/!P; D' file
PATT:201408$ # This shows your current pattern space
HOLD:$ # This shows your current hold buffer
COMM:$ !N # This shows the command that is going to run
PATT:201408$ # This shows the pattern space after the command has ran
201409$
HOLD:$ # This shows the hold buffer after the command has ran
COMM:/^\(.*\)\n\1$/ !P # This shows the command being ran
201408 # Anything without a <TAG:> is what gets printed to STDOUT
PATT:201408$
201409$
HOLD:$
COMM:D
PATT:201409$
HOLD:$
...
...
...
COMM:$ !N
PATT:201409$
HOLD:$
COMM:/^\(.*\)\n\1$/ !P
201409
PATT:201409$
HOLD:$
COMM:D
我也建议,一旦你得到了你的sed
命令被用于,将它们移植到一个更友好的脚本语言编写的想法如awk
,perl
或python
A你确定那是它的样子吗?我在问,因为shell会用双引号替换变量,'$!'扩展为最近执行的后台进程的PID,这很可能导致'sed'看到一些意外的输入...( '$ /'不会被扩展,因为它不是一个有效的变量)。 – twalberg 2014-09-05 20:59:32
@twalberg是的,我只是再次检查,这正是它在代码中的显示方式,它的工作原理。我的电脑很奇怪,但对于任何sed命令,它都不会使用单引号(就像大多数地方所说的那样),但大部分时间都不带引号。对于这一行,只有在使用双引号时才有效。 – user2755209 2014-09-05 21:12:24
@ user2755209在我的'ubuntu'上运行你的命令,我得到这个错误'-bash:!P:event not found'。你在什么操作系统上。 – Jotne 2014-09-05 21:14:20