# Use awk to insert a line after N output

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?

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.

• Hey @steeldriver. What you are saying absolutely makes sense. I read that NR is for input records. But I didn't make the connection with how I was applying the logic. I obviously don't have a full understand. Your solution works! There is one strange thing now; for some reason there are now 2 blank lines between each group of 3. I will see if I can figure out why. Sorry for my ignorance, but what does the "++onr%" do exactly? I think it is doing a count, but I don't recognize the onr. Thank you! – bourne May 28 '14 at 15:35
• Hmmm I changed the second print to print "" and it got ride of the additional blank line. I think I know why now. It is because in the infile there is a chunk of data, followed by a blank line, then another chunk of data. And with your much cleaner awk statement, that original blank line doesn't get stripped out. – bourne May 28 '14 at 15:40
• Oops you are right - the extra newline is an error in my code (print adds a newline by default). As you noted, it can be fixed by changing to print "" - or you could use printf "\n". I will edit the answer. – steeldriver May 28 '14 at 15:43
• thank you! I really appreciate your help. Still have lots to learn. – bourne May 28 '14 at 17:07

do I understand correctly, you are trying to invent

awk '/pattern1|pattern2/ {print $1;} /pattern3/ {print$1 "\n"}' infile

• Hi @vasily-vm. I don't think I am trying to invent. Primarily I am trying to improve my awk code. I need the 3 patterns to be grouped together. The thing is I will end up with multiple groups of 3. After each group of 3 I need to put a blank line due to some formatting restrictions. Cheers – bourne May 28 '14 at 15:38
• sorry, bad wording :( in fact, I propose to split patterns into 2 group: first one will just copy it, second one - will print additional new line after printing the pattern's matching string example si provided in my answer – vasily-vm May 29 '14 at 13:42