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

时间:2019-01-24 17:25:14

标签: bash

具有类似foo.txt的内容

implementation 'com.fasterxml.jackson.core:jackson-core:2.7.3'

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

6 个答案:

答案 0 :(得分:3)

已更新

让我们尝试仅使用sed的简单方法。

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

-n说,除非我告诉你,否则不要打印。
/^$/{g;D;};在每个空白行上说,用以下命令清除所有内容:

  • g:将模式空间的内容替换为保留空间的内容。由于我们从来没有在中放入任何东西,因此会擦除(可能累积很长时间)模式空间。请注意,我可以使用z,因为它是GNU,但我想将其用于下面的非GNU sed,在这种情况下,两者都适用。
  • D:从模式空间中删除现在为空的行,然后阅读下一个。

现在,当(且仅当)我们看到一个空白行时,以前累积的行已被擦除。 D循环回到开头,因此N永远不会看到空白行。

  • N:在模式空间中添加换行符,然后将输入的下一行追加到模式空间中。这是在每一行上执行的操作,空格除外,这之后空格将为空。

这将累积所有非空白,直到1)击中一个空白,这将按上述方法清除并重新启动缓冲区,或者2)我们到达缓冲区完整的EOF。

最后,$p在LAST行(除非最后一行为空,否则它将已经添加到模式空间,这将删除模式空间...)上说,打印模式空间。唯一无法打印的时间是文件的最后一行是空白行。

因此整个逻辑归结为:清理缓冲区中的空行,否则将非空行堆积并最后打印。

  

如果您没有GNU sed,只需将命令放在单独的行上。

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

这会在sed之外运行许多小而简单的任务,因此它可以为sed提供尽可能简单,最直接,最有效的任务描述。它会 读取目标文件两次,但是不必使用空行之前的记录来管理填充,刷新和重新填充模式缓冲区中的数据累积。我认为除非内存不足,否则速度仍然可能会变慢。

答案 1 :(得分:1)

反转文件,将所有内容打印到第一行空白,然后再次反转。

$ tac foo.txt | awk '/^$/{exit}1' | tac
4
5

答案 2 :(得分:1)

使用GNU awk

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

RS是设置为空行的记录分隔符。

END语句显示最后一条记录。

答案 3 :(得分:0)

尝试一下:

 tail +$(($(grep -nE ^$ test.txt | tail -n1 | sed  -e 's/://g')+1)) test.txt
  • grep您的输入文件中的空行。
  • 获取带有尾巴的最后一行=> 5:
  • 删除不必要的:
  • 1添加到5 => 6
  • 6开始的尾巴

答案 4 :(得分:0)

您可以尝试使用sed:

sed -n ':A;$bB;/^$/{x;s/.*//;x};H;n;bA;:B;H;x;s/^..//;p' infile

答案 5 :(得分:0)

使用GNU sed:

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