Use awk to insert a line after N output

awk

I have a text file filled with a bunch of data.
I need to pull out lines that contain specific strings. I accomplished this with awk using the following:

awk '/pattern1|pattern2|pattern3/ {print;}' infile

I then need to put a new line (\n) after ever 3rd line. So it would need to look like this

pattern1
pattern2
pattern3
<new line>
pattern1...

I was able to accomplish this by piping the first command into another awk statement

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

I figure that there must be a more efficient way of doing this so I started looking to see how I could combine the two commands together. I tried the following:

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

I figured this would work but the output is completely unpredictable, sometimes there are 5 lines grouped together, groups of 2 lines, but no lines of 3.

I was thinking that perhaps there was a delimiter issue so I tried playing with the -F option and setting the IFS but neither changed the output.

I figure I am doing something stupid in the way I have tried to combine the pattern match with the if statement but I haven't been able to figure out the combination.

Is what I am trying to do possible in a single awk command? And if so, where am I going wrong?

Best Answer

The problem with your attempted solution is that awk's NR is a count of the input records, whereas you want to insert the newline based on the count of the number of output records.

I don't think awk keeps such a count natively, but you could do something like

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

in which we define a new variable onr (for output number of record - the variable name is arbitrary) and increment it every time we match/print the wanted text, then check if that is divisible by 3 and if so print a newline.

Related Question