2014-09-05 108 views
0

我在下面有一行SED,这是我每个月运行的批处理命令。它是由我之前的人写的,我期待了解这些代码的各个部分。从这两个输出中我可以看出,当顺序行重复时,它会占用一行并删除另一行,我只是不明白它是如何完成这一行的。SED代码解释

sed "$!N; /^\(.*\)\n\1$/!P; D" finalish.txt > final.txt 

Exmple的 - Finalish.txt

201408 
201409 
201409 
201409 
201409 

- Final.txt

201408 
201409 
+0

A你确定那是它的样子吗?我在问,因为shell会用双引号替换变量,'$!'扩展为最近执行的后台进程的PID,这很可能导致'sed'看到一些意外的输入...( '$ /'不会被扩展,因为它不是一个有效的变量)。 – twalberg 2014-09-05 20:59:32

+0

@twalberg是的,我只是再次检查,这正是它在代码中的显示方式,它的工作原理。我的电脑很奇怪,但对于任何sed命令,它都不会使用单引号(就像大多数地方所说的那样),但大部分时间都不带引号。对于这一行,只有在使用双引号时才有效。 – user2755209 2014-09-05 21:12:24

+0

@ user2755209在我的'ubuntu'上运行你的命令,我得到这个错误'-bash:!P:event not found'。你在什么操作系统上。 – Jotne 2014-09-05 21:14:20

回答

2

不会去到sed的基础知识,这里是你的sed命令细分:

  • $!N:如果没有文件结尾,下一行追加到模式空间。这两行将被换行符分开(\n)。在这个时候你的模式空间是201408\n201409
  • /^\(.*\)\n\1$/!P:如果将模式空间包含一个换行(\n)分隔开的两个类似的内容,然后P RINT直到第一换行符(\n)。所以这将打印201408到STDOUT。在第二次迭代期间,模式空间将有201409\n201409,并且因为它失败正则表达式,没有打印,我们继续下一个命令。
  • DD直到第一个换行符(\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,perlpython

0

这不会帮助你理解sed,但这里是一个awk,仅仅得到独特的线条。

awk '!seen[$0]++' finalish.txt 
201408 
201409 
+0

这将挑选出不相邻的等效线路,这似乎并不是预期的效果...... – twalberg 2014-09-05 21:13:33

+0

@twalberg然后有些人会这样做:awk NR> 1 && $ 0!= a {print a} {a = $ 0} END {print}'file' – Jotne 2014-09-05 21:18:37