获取最后一组非空行

l0b*_*0b0 3 sed awk perl text-processing

我正在运行一个 cron 作业,它应该只得到iostat -d 1 2. 这需要一些解析:如果每组的长度未知,从标准输入到标准输出获取最后一组非空行的最简单方法是什么?

坏/非工作解决方案:

  • tail因为我仍然需要计算最后一组中的行数。iostat -d 1 2 | tail -$(echo "$(iostat -d 1 2 | wc -l) / 2" | bc)取决于相同的集合大小。
  • split/csplit因为它们输出到文件,并保留数据的无用部分。
  • iostat -d 1 2 | sed '1,/^$/d' | sed '1,/^$/d' 仅在这种特殊情况下有效,因为它获取第三组非空行,但还包括任何尾随换行符。
  • iostat -d 1 2 | tac | sed '1,/^$/d' | sed '/^$/q'是一个稍微好一点的技巧:反转并打印第一组。然而,由于最后iostat输出一个空行,我们首先删除它,然后打印直到反向输出中的下一个空行。其他命令可能会在最后输出任意数量的换行符,因此这不是通用的解决方案。如果您想保留原始顺序,请再次反转。
  • grep -Pwith\Z似乎只检测到 EOL,而不是 EOF。

dog*_*ane 9

您可以使用awk的段落模式(当 RS 为空字符串时)。这样每个“集合”都是一个记录,您可以轻松打印出最后一个。

iostat -d 1 2 | awk -vRS= 'END{print}'
Run Code Online (Sandbox Code Playgroud)

  • 将 `RS` 赋值放在 `BEGIN` 块中更有效。 (3认同)
  • 最好使`awk -vRS='END{print}'`。首先,因为 `"\n\n"` 版本如果输入末尾有两个以上的空行,就会打印一条空记录。其次,因为某些版本的 awk 不允许 `RS` 超过一个字符。空的“RS”表示“段落模式”,其中两个或多个换行符的任何序列分隔记录,这是 POSIX 所要求的。 (3认同)

gle*_*man 5

perl -00 是一次阅读一段的好方法,所以最后一段是:

perl -00 -ne '$para = $_; END {print $para}'
Run Code Online (Sandbox Code Playgroud)