首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从文件中获取最后一个空行之后的所有行?

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

Stack Overflow用户
提问于 2019-01-25 01:25:14
回答 6查看 987关注 0票数 2

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

代码语言:javascript
复制
1
2

3

4
5

假设行数可以是不同的,我如何获得其中以4和5开头的行(最后一个空行之后的所有行)?

EN

回答 6

Stack Overflow用户

发布于 2019-01-25 04:04:59

已更新

让我们仅用sed来尝试一种稍微简单一点的方法。

代码语言:javascript
复制
$: sed -n '/^$/{g;D;}; N; $p;' foo.txt
4
5

-n说除非我告诉你否则不要打印。

/^$/{g;D;};在每个空白行上说,用以下命令清除所有内容:

  • g:将模式空间的内容替换为保留空间的内容。由于我们从未放入任何内容,这将擦除(可能是长期累积的)模式空间。请注意,我本可以使用z,因为这是GNU,但我想在下面的非GNU模式中使用它,在这种情况下,这适用于both.
  • D:从模式空间中删除现在为空的行,然后阅读下一行。

现在,如果(且仅当)我们看到空行,则先前累积的行将被擦除。D循环回到开头,因此N永远不会看到空行。

  • N:在模式空间中添加一个换行符,然后将下一行输入附加到模式空间。在除空格之外的每一行上都会执行此操作,否则模式空间将为空。

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

最后,$p在最后一行上说(除非最后一行是空的,否则已经添加到模式空间中,这将删除模式空间...),打印模式空间。只有当文件的最后一行是空行时,才不会打印任何内容。

因此,整个逻辑可以归结为:在空行上清除缓冲区,否则将非空行堆叠在一起并在末尾打印。

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

代码语言:javascript
复制
sed -n '
  /^$/{
   g
   D
  }
  N
  $p
' foo.txt

替代方案

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

或者,如果你想在简单的步骤中完成它,不要介意更多的进程做更少的工作,而更喜欢消耗更少的内存:

代码语言:javascript
复制
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提供对任务最简单、最直接和最有效的描述。它将读取目标文件两次,但不必管理填充、刷新和重新填充模式缓冲区中积累的数据,并在空白行之前添加记录。我认为,除非你是内存受限的,否则仍然可能更慢。

票数 3
EN

Stack Overflow用户

发布于 2019-01-25 03:45:06

反转文件,打印直到第一个空行的所有内容,再反转一次。

代码语言:javascript
复制
$ tac foo.txt | awk '/^$/{exit}1' | tac
4
5
票数 1
EN

Stack Overflow用户

发布于 2019-01-25 22:32:40

使用GNU awk

代码语言:javascript
复制
awk -v RS='\n\n' 'END{printf "%s",$0}' file

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

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54352272

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档