Search code examples
shellunixawkposix

Reverse line order except header


With a shell command I want to reverse the lines of a text file, excluding the header line.

Number,Letter,Person
1,a,Alice
2,b,Bob
3,c,Claire

should become

Number,Letter,Person
3,c,Claire
2,b,Bob
1,a,Alice

I'm looking for both an "in place" solution (change original file) and a streaming solution (read original file from stdin and print result to stdout).

Ideally, the command or script would be POSIX compatible, but other solutions could also be interesting. A oneliner would be nice.

I'm also interested in the performance/complexity of any solution.


Solution

  • Here is an awk command to do this:

    awk '{a[NR]=$0} END{print a[1]; for (i=NR; i>1; i--) print a[i]}' file
    
    Number,Letter,Person
    3,c,Claire
    2,b,Bob
    1,a,Alice
    

    Here a[1] represents header record. Remaining entries in associative array a represent rows with the index as record number.

    Alternatively, using head, tail, cat:

    { head -1 f && tail -n +2 file | tac; } > file._tmp && mv file._tmp file
    
    Number,Letter,Person
    3,c,Claire
    2,b,Bob
    1,a,Alice