2011-06-06 95 views
12

开门见山,'N'命令如何在sed中工作?

 
$ cat in.txt 
a 
b 
c 
d 
$ sed '=;N' in.txt 
1 
a 
b 
3 
c 
d 

它看起来像每隔一行 'N' 命令的作品。也许这是很自然的,因为命令'N'加入下一行并改变当前行号。但是,

 
$ sed 'N;$!P;$!D;$d' thegeekstuff.txt 

(我看到这个here
上面的例子删除一个文件的最后两行。这不仅适用于偶数编号的文件,也适用于奇数编号的文件。所以在这个例子中,'N'命令在每一行都运行。
有什么区别?

你能告诉我,为什么我不能看到最后一行,当我运行sed的这样吗?从info sed

 
# sed N odd-lined-file.txt 

回答

19

摘录:

`sed' operates by performing the following cycle on each lines of 
input: first, `sed' reads one line from the input stream, removes any 
trailing newline, and places it in the pattern space. Then commands 
are executed; each command can have an address associated to it: 
addresses are a kind of condition code, and a command is only executed 
if the condition is verified before the command is to be executed. 
... 
When the end of the script is reached, unless the `-n' option is in 
use, the contents of pattern space are printed out to the output 
stream, 
... 
Unless special commands (like 'D') are used, the pattern space is 
deleted between two cycles 

... 

`N' 
    Add a newline to the pattern space, then append the next line of 
    input to the pattern space. If there is no more input then `sed' 
    exits without processing any more commands. 

... 

`D' 
    Delete text in the pattern space up to the first newline. If any 
    text is left, restart cycle with the resultant pattern space 
    (without reading a new line of input), otherwise start a normal 
    new cycle. 

这应该差不多解决您的查询。但我依然会尽量解释您的三种不同的情况:

案例1:

  1. sed读取输入线。 [现在模式空间有1行。]
  2. =打印当前行没有。
  3. N读取下一行到图案空间。[现在有2行模式空间。]
    • 如果没有下一行读到这里,然后SED退出。 [即:在奇数行的情况下,sed在这里退出 - 因此最后一行被吞下而不打印。]
  4. sed打印模式空间并清除它。 [模式空间为空。]
  5. 如果EOF到达这里sed退出。这里在偶数行的情况下,退出的sed:否则从步骤1 [即重新启动完整的周期。]

摘要:在这种情况下,sed每次读取2行并打印2行。最后一行被吞噬,有奇数行(见第3步)。

CASE 2:

  1. sed读取从输入的线。 [现在模式空间有1行。]
  2. N将下一行读入模式空间。 [现在模式空间中有2行。]
    • 如果它在这里失败退出。这只有在有1行时才会发生。
  3. 如果它不是最后一行($!)从打印模式空间的第一行(P)。 [打印来自图案空间的第一行。但模式空间中仍然有2行。]
  4. 如果它的最后一行($!)从模式空间删除第一行(D)[现在模式空间中只有1行(第二行)。]和重新从步骤2开始执行指令周期。并因其命令D(请参阅上面的摘录)
  5. 如果它的最后一行($)则删除(d)完整的模式空间。 [即。达到EOF] [在开始此步骤之前,模式空间中有2行,现在由d清除 - 在此步骤结束时,模式空间为空。]
  6. sed自动停在EOF。

小结:在这种情况下:

  • sed首先读取2行。
  • 如果有下一行可以读取,打印第一行并读取下一行。
  • 否则从缓存中删除两行。 这样它总是删除最后2行。

情况3:
及其相同的大小写CASE:1,只是删除从它的第2步。

+0

好吧,我不能完全理解这一点。这意味着如果只有模式空间不是空的,那么'N'命令将在每行上运行?并在模式空间为空时运行其他每一行? – plhn 2011-06-09 01:00:53

+1

考虑到你的评论,我已经更新了答案。请检查一次。 – ssapkota 2011-06-11 11:27:06

+0

非常感谢你!!!!!!!! – plhn 2011-06-25 18:18:52