【问题标题】:What does the 'N' command do in sed?sed 中的“N”命令有什么作用?
【发布时间】:2021-07-10 18:53:39
【问题描述】:

看起来'N'命令在每一行都有效:

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

也许这很自然,因为命令“N”加入下一行并更改当前行号。但是(我看到了这个here):

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

上面的例子删除了文件的最后两行。这不仅适用于偶数行编号的文件,也适用于奇数行编号的文件。在此示例中,“N”命令在每一行上运行。有什么区别?

你能告诉我为什么当我像这样运行 sed 时看不到最后一行:

# sed N odd-lined-file.txt

【问题讨论】:

    标签: sed


    【解决方案1】:

    摘自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 步重新开始整个循环。 [即:如果是偶数行,则 sed 退出此处。]

    总结:在这种情况下,sed 一次读取 2 行并打印 2 行。最后一行被吞下,有奇数行(见步骤 3)。

    案例 2:

    1. sed 从输入中读取一行。 [现在模式空间中有 1 行。]
    2. N 将下一行读入模式空间。 [现在模式空间中有 2 行。]
      • 如果失败退出这里。仅当有 1 行时才会发生这种情况。
    3. 如果不是最后一行($!),则从模式空间打印第一行(P)。 [打印模式空间的第一行。但是模式空间中仍然有 2 行。]
    4. 如果不是最后一行($!),则从模式空间中删除第一行(D) [现在模式空间中只有一行(第二行)。]并从第 2 步重新开始命令循环。这是因为命令 D(请参阅上面的摘录)
    5. 如果它的最后一行($) 则删除(d) 完整的模式空间。 [IE。达到 EOF ] [在开始这一步之前,模式空间中有 2 行现在被 d 清理 - 在这一步结束时,模式空间是空的。]
    6. sed 在 EOF 处自动停止。

    总结:在这种情况下:

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

    案例 3:
    与 CASE:1 相同,只需去掉其中的第 2 步即可。

    【讨论】:

    • 好吧,我无法彻底理解这一点。这意味着如果只有模式空间不为空,'N' 命令将在每一行上运行?并在模式空间为空时每隔一行运行一次?
    • 考虑到您的评论,我已经更新了答案。请检查一次。
    • sed中的nN有什么区别?
    • D 最多删除并包括第一个换行符,对吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-24
    • 2013-07-08
    • 1970-01-01
    • 2017-04-18
    • 2022-07-05
    • 1970-01-01
    • 2014-11-01
    相关资源
    最近更新 更多