【问题标题】:How does Next line counter get updated in sed?下一行计数器如何在 sed 中更新?
【发布时间】:2019-09-13 07:59:56
【问题描述】:

我无法理解 sed 如何读取下一行。

他是我的理解,请纠正我的错误

/pattern/p 所以这会逐行读取并打印是否匹配行

N;/pattern/d 所以这会一起读取两行,如果存在模式,则删除两者,在下一个循环中,sed 是否开始从第 2 行或第 3 行读取,并且行已经被 N 读取?

:a N; /pattern/{:b;n;/pattern/bb; ba}

现在在上面的情况下是内部循环。 n 多次读取下一行,如果然后返回 a。现在我的问题是当控制权回到 a 时,N 会读到什么

例子

这是示例文件

line 11
line 13
line 13
line 13
line 14
line 15
line 16

最初 N 将包含 . line 11 \n line 13 如果模式是 13 然后在内部循环中 n 再次读取下一行并返回直到 13 不存在然后返回到 a

现在我的问题是N 的值是多少?会是吗

line 14 \n line line 15 。或line 14 \n line 13

【问题讨论】:

    标签: linux ubuntu sed


    【解决方案1】:

    所有这些行为都可以使用 GNU 调试器 --debug 观察到。

    ▶ data="line 11
    line 13      
    line 13     
    line 13                  
    line 14         
    line 15     
    line 16"     
    

    输出:

    ▶ gsed ':a N; /13/{:b;n;/13/bb; ba}' <<< $data                 
    line 11
    line 13
    line 13
    line 13
    line 14
    line 15
    line 16
    

    调试器中的输出视图:

    ▶ gsed --debug ':a N; /13/{:b; n; /13/bb; ba}' <<< $data
    
    SED PROGRAM:
      :a
      N
      /13/ {
        :b
        n
        /13/ b b
        b a
      }
    INPUT:   'STDIN' line 1
    PATTERN: line 11
    COMMAND: :a
    COMMAND: N
    PATTERN: line 11\nline 13
    COMMAND: /13/ {
    COMMAND:   :b
    COMMAND:   n
    line 11
    line 13
    PATTERN: line 13
    COMMAND:   /13/ b b
    COMMAND:   :b
    COMMAND:   n
    line 13
    PATTERN: line 13
    COMMAND:   /13/ b b
    COMMAND:   :b
    COMMAND:   n
    line 13
    PATTERN: line 14
    COMMAND:   /13/ b b
    COMMAND:   b a
    COMMAND:   :a
    COMMAND:   N
    PATTERN: line 14\nline 15
    COMMAND:   /13/ {
    COMMAND:   }
    END-OF-CYCLE:
    line 14
    line 15
    INPUT:   'STDIN' line 7
    PATTERN: line 16
    COMMAND:   :a
    COMMAND:   N
    END-OF-CYCLE:
    line 16
    

    现在我的问题是当控制权回到 a 时,N 会读到什么

    如你所见:

    PATTERN: line 14
    COMMAND:   /13/ b b
    COMMAND:   b a
    COMMAND:   :a
    COMMAND:   N
    PATTERN: line 14\nline 15
    

    所以紧跟在ba之后的命令是:a,然后是N,而N具有读取输入流的下一行并将其附加到模式空间的效果。

    【讨论】:

      【解决方案2】:
      :a N; /pattern/{:b;n;/pattern/bb; ba}
      

      让我们让它更具可读性并添加 cmets:

      # At the start there is one line read from input
      # read into pattern space
      
      # define label with the name 'a'
      :a
      
      # append next line to pattern space
      N
      
      # Match pattern space with 'pattern'
      /pattern/{
         # go here if matching successfull
      
         # define label 'b'
         :b
      
         # read the next line into pattern space
         # current pattern space is removed
         n
      
         # match pattern space with /pattern/
         /pattern/{
      
            # goto label 'b'
            bb
         }
      
         # goto label 'a'
         ba
      
      }
      

      在下一个周期中,sed 是否从第 2 行或第 3 行开始读取,并且行已被 N 读取?

      您无法返回输入。输入有线条。 N 将下一行从输入附加到模式空间。一旦输入被读取,您将无法重新读取它。 d 删除模式空间并开始循环(即类似于n; b&lt;label on the beginning&gt;)。

      我的问题是当控制回到 a 时,N 会读到什么

      当模式不再匹配时,它会跳转到:a

         not
         pattern # jumps into /pattern/{ .. }
         pattern # jumps into inside /pattern/bb
         pattern
         pattern
         not # get's back to :a
      

      我的问题是 N 的值是多少?

      N 没有值,它是一个命令,将输入中的下一行附加到模式空间中。

      N 命令之后的模式空间内容将有两行。在您最初提供的示例中,它将有line 11\nline13 然后是line14\nline15。用一个简单的脚本很容易看到:

      sed -n ':a N; p; /13/{:b;n;/13/bb; ba}' <<EOF
      line 11
      line 13
      line 13
      line 13
      line 14
      line 15
      line 16
      EOF
      

      所有命令的解释都可以在man sed中找到。 This 是对 sed 的一个很好的介绍。

      【讨论】:

        猜你喜欢
        • 2020-12-07
        • 2023-04-11
        • 1970-01-01
        • 1970-01-01
        • 2023-04-09
        • 2012-05-04
        • 1970-01-01
        • 2020-09-05
        • 1970-01-01
        相关资源
        最近更新 更多