使用awk在N个输出后插入一行

bou*_*rne 7 awk

我有一个填充了一堆数据的文本文件。我需要提取包含特定字符串的行。我使用 awk 使用以下方法完成了此操作:

awk '/pattern1|pattern2|pattern3/ {print;}' infile
Run Code Online (Sandbox Code Playgroud)

然后我需要在第 3 行之后放置一个新行 (\n)。所以它需要看起来像这样

pattern1
pattern2
pattern3
<new line>
pattern1...
Run Code Online (Sandbox Code Playgroud)

我能够通过将第一个命令通过管道传输到另一个 awk 语句来完成此操作

awk -F '\n' '/pattern1|pattern2|pattern3/ { print; }' infile | awk '{ if ((NR % 3) == 1) printf("\n"); print; }'
Run Code Online (Sandbox Code Playgroud)

我认为必须有一种更有效的方法来做到这一点,所以我开始寻找如何将这两个命令组合在一起。我尝试了以下方法:

awk '/pattern1|pattern2|pattern3/ { if ((NR % 3) ==1 ) printf("\n"); print; }'
Run Code Online (Sandbox Code Playgroud)

我认为这会起作用,但输出是完全不可预测的,有时有 5 行组合在一起,2 行为一组,但没有 3 行。

我在想可能存在分隔符问题,所以我尝试使用 -F 选项并设置 IFS,但都没有改变输出。

我想我在尝试将模式匹配与 if 语句结合起来的方式上做了一些愚蠢的事情,但我无法弄清楚组合。

我在单个 awk 命令中尝试做的事情是可能的吗?如果是这样,我哪里出错了?

ste*_*ver 7

您尝试的解决方案的问题是 awkNR输入记录的计数,而您想根据输出记录数的计数插入换行符。

我不认为 awk 本身就保持这样的计数,但你可以做类似的事情

awk '/pattern1|pattern2|pattern3/ {print; if (++onr%3 == 0) print ""; }' infile
Run Code Online (Sandbox Code Playgroud)

在其中我们定义了一个新变量onr(用于记录的输出数- 变量名称是任意的)并在每次匹配/打印所需文本时增加它,然后检查是否可以被 3 整除,如果可以,则打印换行符。