Lum – How to reorder a large number of columns

columnssort

I'm looking for a pipeable one-liner to reorder a large number of columns (where manually entering the column numbers in e.g. an awk command such as awk '{print $3,$2,$1}' is not feasible). The order could be given by a sorting scheme (alphabetical, numerical – so like 'sort' but acting on columns rather than rows.) or be arbitrarily given in a text file.

Best Answer

Here is a streamable solution.

I assume you want to sort based on the first row of the columns, otherwise adapt to get the sorting key from somewhere else.

Generate sorting key (reusing Rush's array):

echo -e  "2 1 3\n5 4 6\n8 7 9" > data

key=$(head -n1 data | tr -s ' ' | tr ' ' '\n' | cat -n \
      | sort -k2 | sed 's/^ *\(.*\)\t.*/\1/')

$key now holds:

2
1
3

Now use the key to sort columns:

cat data | awk -v key="$key" '
BEGIN { split(key, order, "\n") }

{ 
  for(i in order) { 
    printf("%s ", $order[i])
  }
  printf("\n");
}'

Output:

1 2 3 
4 5 6 
7 8 9
Related Question