nando
nando

Reputation: 377

Linux - flip last bottom lines only, with awk

We are currently learning some awk commands to manipulate/rearrange text on files.

our original text goes like this..1998

    Ford,mondeo,1998,5800
    ford,fiesta,1994,4575
    Chevy,impala,1998,1000
    Plymouth,Fury,1992,2000
    Dodge,charger,1989,5950
    Ford,F150,1991,1450

It's asking us to rearrange the columns (part one) which i already did.. but at the same time to flip the bottom two lines (part two) so that it looks like this

1998 5800 Ford mondeo
1994 4575 ford fiesta
1998 1000 Chevy impala
1992 2000 Plymouth Fury
1991 1450 Ford  F150
1989 5950 Dodge charger

again, i got the order and spacing taken care of, but how do i switch the bottom two lines (or flip them). by the way this can only be done with awk.

Upvotes: 0

Views: 127

Answers (2)

F. Knorr
F. Knorr

Reputation: 3055

The following code switches the last two lines of a file:

awk '{array[NR%3]=$0; 
    if(NR>2){print array[(NR+1)%3]}}
    END{print array[NR%3]; 
        print array[(NR-1)%3]}' test

To do so, we store the last three lines in an array. We print a line only when line after the next line is read. Finally, we take last two lines from the array, invert the order and print it.

A more detailed description of the code:
We store the content of the current line ($0) in an array. As we only need to keep track of the last three lines read, the index of our array can be limited to the values 0, 1, and 2. We achieve this by using the modulo operator (NR % 3).
When reaching the third line, we print the last but one line (if(NR>2)...). This is save, as in this case there are still two lines in the array that we can handle separately.
When the end of the file is reached (END{...}), we print the last two lines in inverse order.
Why did we use NR%3 (and not NR%2)? If there were only two lines in our input file, printing must happen in the END-block and not before!

Upvotes: 3

karakfa
karakfa

Reputation: 67507

this will swap the last two lines and prints omitted for the others

$ tac cars | awk 'NR==1{getline one} 
                  NR==2{print; print one} 
                   NR>2{print "omitted"}' | tac  
omitted
omitted
omitted
Plymouth,Fury,1992,2000
Dodge,charger,1989,5950

you can add formatting. Similarly can be without tac with logic in END block.

UPDATE: awk only solution: keep two lines in memory, when done print them in reverse order

$ awk 'NR>2{print pp} 
           {pp=p;p=$0} 
        END{print p;print pp}' car 

Ford,mondeo,1998,5800                                                                                          
ford,fiesta,1994,4575                                                                                          
Chevy,impala,1998,1000                                                                                         
Plymouth,Fury,1992,2000                                                                                        
Ford,F150,1991,1450                                                                                            
Dodge,charger,1989,5950    

Upvotes: 1

Related Questions