Thursday, February 8, 2018

AWK: Printing lines after they were already processed



I have a simple file, which is processed by my awk script:



AAAAA BBBBBB
CCCCC DDDDDD
EEEEE FFFFFF
GGGGG HHHHHH
IIIII JJJJJJ



First, I want to print out one of the last lines, so I start with



#!/usr/bin/awk
{if (NR==5){print $0;}}


to get IIIII JJJJJJ as a result.



Now I want to print line 2 after line 5 was printed out. So I change my script to this:




#!/usr/bin/awk
{if (NR==5){print $0; NR=2;}
if (NR==2){print $0;}


But in this case, it is a never ending loop. How can I print line 5 first and then line 2 without printing line 5 again?



Expected output for clarity:




IIIII JJJJJJ
CCCCC DDDDDD

Answer



How about this:



awk '{if (NR==2){x=$0} else if (NR==5) {y=$0}} END {print y; print x}' input 


As we scan the file line-by-line, we store the lines we are interested in in some variables, and then we print them at the end.




And here's a slight simpler alternative:



awk '{if (NR==2){x=$0} else if (NR==5) {print $0; print x}}' input 


This only stores line 2 in a variable. When we reach line 5, we print it and then we print line 2 from the variable.



Edit: As William Pursell pointed out, a more idiomatic way to write the above code would be




awk 'NR==2 {x=$0} NR==5 {y=$0} END {print y; print x}' input 


and



awk 'NR==2 {x=$0} NR==5 {print $0; print x}' input 

No comments:

Post a Comment

plot explanation - Why did Peaches' mom hang on the tree? - Movies & TV

In the middle of the movie Ice Age: Continental Drift Peaches' mom asked Peaches to go to sleep. Then, she hung on the tree. This parti...