“N”命令如何在sed中起作用?

时间:2011-06-06 17:33:17

标签: 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时我看不到最后一行吗?

# sed N odd-lined-file.txt

1 个答案:

答案 0 :(得分:25)

摘录自info sed

`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退出此处。 [ ie:如果出现奇数行,则sed退出此处 - 因此吞下最后一行而不打印。]
  4. sed打印图案空间并清除它。 [图案空间为空。]
  5. 如果此EOF已到达sed Else重启步骤1中的完整周期。 [ ie:如果是偶数行,则sed退出此处。]
  6. 总结:在这种情况下,sed读取2行并一次打印2行。吞下最后一行,有奇数行(见步骤3)。

    案例2:

    1. sed从输入中读取一行。 [现在模式空间中有1行。]
    2. N将下一行读入模式空间。 [现在模式空间中有2行。]
      • 如果失败则退出此处。仅当有1行时才会发生这种情况。
    3. 如果不是最后一行($!),则从模式空间打印第一行(P)。 [打印图案空间的第一行。但模式空间中仍有2行。]
    4. 如果不是最后一行($!)从模式空间中删除第一行(D)[现在模式空间中只有一行(第二行)。< / strong>]和从步骤2重新启动命令周期。由于命令D (参见上面的摘录)
    5. 如果最后一行($)则删除(d)完整的模式空间。 [即。达到EOF] [在开始此步骤之前,模式空间中有2行现在由d清除 - 在此步骤结束时,模式空间为空。] < / LI>
    6. sed会自动停在EOF。
    7. 总结:在这种情况下:

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

      案例3:
      与CASE:1的情况相同,只需从中删除第2步。