[英]How to get all lines from a file after the last empty line?
具有诸如foo.txt之类的内容文件
1
2
3
4
5
假设行数可以不同,我如何从中取出以4和5开头的行(所有行都在最后一个空行之后)?
让我们尝试使用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
尽可能简单,最直接,最有效地描述任务。 它会读取目标文件的两倍,但不会有管理灌装,冲洗,和一个空行之前补充与记录模式缓冲区的数据积累。 我认为,除非内存不足,否则速度可能仍会较慢。
反转文件,将所有内容打印到第一行空白,然后再次反转。
$ tac foo.txt | awk '/^$/{exit}1' | tac
4
5
使用GNU awk
:
awk -v RS='\n\n' 'END{printf "%s",$0}' file
RS
是设置为空行的记录分隔符。
END
语句打印最后一条记录。
尝试这个:
tail +$(($(grep -nE ^$ test.txt | tail -n1 | sed -e 's/://g')+1)) test.txt
5:
:
1
到5
=> 6
6
开始的尾巴 您可以尝试使用sed:
sed -n ':A;$bB;/^$/{x;s/.*//;x};H;n;bA;:B;H;x;s/^..//;p' infile
使用GNU sed:
sed ':a;/$/{N;s/.*\n\n//;ba;}' file
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.