Create a function to transpose the file (make rows will become columns and columns will become strings):
transpose () { awk '{for (i=1; i<=NF; i++) a[i,NR]=$i; max=(max<NF?NF:max)} END {for (i=1; i<=max; i++) {for (j=1; j<=NR; j++) printf "%s%s", a[i,j], (j<NR?OFS:ORS) } }' }
This simply loads all the data into a two-dimensional array a[line,column] , and then prints it as a[column,line] , so that it wraps the given input. The transpose () { } wrapper is used to store it as a bash function. You just need to copy it to the shell (or to ~/.bashrc if you want it to be a constant function available anytime you open a session).
Then, using this, we can easily solve the problem using sort -n -k2 : sort numerically based on column 2. Then rearrange.
$ cat a | transpose | sort -n -k2 | transpose john sarah mark 5 10 20 zxy
If you want to have a good format as the final output, just connect to column as follows:
$ cat a | transpose | sort -n -k2 | transpose | column -t john sarah mark 5 10 20 zxy
Step by step:
$ cat a | transpose sarah 10 x mark 20 y john 5 z $ cat a | transpose | sort -n -k2 john 5 z sarah 10 x mark 20 y $ cat a | transpose | sort -n -k2 | transpose john sarah mark 5 10 20 zxy
source share