代码之家  ›  专栏  ›  技术社区  ›  Ivan Koshelev

如何从文件中获取最后一个空行之后的所有行?

  •  1
  • Ivan Koshelev  · 技术社区  · 7 年前

    有一个像foo.txt这样的包含内容的文件

    1
    2
    
    3
    
    4
    5
    

    假设行的数量可以不同,如何从中取出以4和5开头的行(最后一个空行之后的所有行)?

    6 回复  |  直到 7 年前
        1
  •  3
  •   Paul Hodges    7 年前

    更新

    让我们尝试一种稍微简单的方法 sed .

    $: sed -n '/^$/{g;D;}; N; $p;' foo.txt
    4
    5
    

    -n 说除非我告诉你不要打印。
    /^$/{g;D;};

    • g :将图案空间的内容替换为保留空间的内容。因为我们什么都没放 在里面 ,这将删除(可能是长期累积的)模式空间。注意我本可以用 z 既然这是GNU,但我想把它改成非GNU 塞德 在下面,在这种情况下,这对两者都有效。
    • D :从模式空间中删除现在为空的行,然后读取下一行。

    循环回到开始,所以 N 永远看不到空行。

    • :向模式空间添加新行,然后将下一行输入追加到模式空间。这是在 除空格外的行,之后的图案空间将为空。

    这将累积所有非空,直到1)命中一个空,这将清除并重新启动如上所述的缓冲区,或2)我们到达缓冲区完好无损的EOF。

    $p 在最后一行(如果最后一行为空,则该行已添加到图案空间中,如果最后一行为空,则该行将删除该图案空间…),打印该图案空间。只有当文件的最后一行是一个空行时,才会没有任何内容可供打印。

    所以整个逻辑可以归结为:清除空行上的缓冲区,否则将非空行堆积起来并在最后打印。

    如果你没有GNU 塞德

    sed -n '
      /^$/{
       g
       D
      }
      N
      $p
    ' foo.txt
    

    候补

    上述方法是有效的,但可能在某些数据集上建立一个非常大的模式缓冲区。如果这不是问题,那就继续吧。

    或者,如果您希望以简单的步骤进行,请不要介意更多的进程在每个进程中做更少的工作,而希望使用更少的内存:

    last=$( sed -n /^$/= foo.txt|tail -1 ) # find the last blank
    next=$(( ${last:-0} + 1 ))             # get the number of the line after
    cmd="$next,\$p"                        # compose the range command to print
    sed -n "$cmd" foo.txt                  # run it to print the range you wanted
    

    这会在 塞德 这样它就可以 塞德 对任务最简单、最直接、最有效的描述。它 读取目标文件两次,但不必在空行之前用记录管理填充、刷新和重新填充模式缓冲区中的数据累积。我想,除非你有记忆限制,否则速度可能会慢一些。

        2
  •  1
  •   John Kugelman Michael Hodel    7 年前

    $ tac foo.txt | awk '/^$/{exit}1' | tac
    4
    5
    
        3
  •  1
  •   oliv    7 年前

    使用GNU awk :

    awk -v RS='\n\n' 'END{printf "%s",$0}' file
    

    RS

    这个 END 语句打印最后一条记录。

        4
  •  0
  •   Derviş Kayımbaşıoğlu    7 年前

    试试这个:

     tail +$(($(grep -nE ^$ test.txt | tail -n1 | sed  -e 's/://g')+1)) test.txt
    
    • grep空行的输入文件。
    • 5:
    • 去掉不必要的 :
    • 添加 1 5 => 6
    • 尾部起点
        5
  •  0
  •   ctac_    7 年前

    你可以试试sed:

    sed -n ':A;$bB;/^$/{x;s/.*//;x};H;n;bA;:B;H;x;s/^..//;p' infile
    
        6
  •  0
  •   SLePort    7 年前

    sed ':a;/$/{N;s/.*\n\n//;ba;}' file
    
    推荐文章