Sort all rows horizontally by reference to columns in a particular row

sorttext processing

I need to sort horizontally, not vertically, and sort seems to be designed for vertical operation. q E.g., I have three rows as follows:

banana/orange/apple/mango
potato/tomato/onion/garlic
chair/table/carpet/window

All rows have the same number of columns, separated by a /. I want the columns to be re-arranged according to alphabetical order in row 1. So it will become:

apple/banana/mango/orange
onion/potato/garlic/tomato
carpet/chair/window/table

This might be better visualized as shown below:

text in colored columns

i.e., like sort-by-column in a spreadsheet.

Best Answer

With GNU awk, you may dictate the order in which arrays are traversed by setting sorted_in within PROCINFO. In this instance, set it to @val_str_asc to force arrays to be traversed in ascending order of values.

Next split the first line into an array a Finally, for each line, traverse the array and print fields corresponding to the keys as they are retrieved.

awk -F'/' 'BEGIN{PROCINFO["sorted_in"]="@val_str_asc"};
   FNR == 1{n = split($0, a)};
   {x=0; for (k in a) printf "%s%s", $k, ++x == n? "\n": FS}' file

apple/banana/mango/orange
onion/potato/garlic/tomato
carpet/chair/window/table

Or, with python

from __future__ import print_function
with open('file') as f:
    keys = next(f).rstrip('\n').split('/')
    print(*sorted(keys), sep='/')
    for line in f:
            g = (m for l, m in sorted(zip(keys, line.rstrip('\n').split('/'))))
            print(*g, sep='/')

apple/banana/mango/orange
onion/potato/garlic/tomato
carpet/chair/window/table
Related Question