具有类似foo.txt的内容
implementation 'com.fasterxml.jackson.core:jackson-core:2.7.3'
假设行数可以不同,我如何从中取出以4和5开头的行(最后一行空行之后的所有内容)?
答案 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
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