Usar bash para ordenar los datos horizontalmente

Tengo un archivo lleno de datos en columnas

sarah mark john 10 20 5 xyz 

Quiero ordenar los datos para que las columnas permanezcan intactas, pero la segunda fila está en orden creciente por lo que se ve así:

 john sarah mark 5 10 20 zxy 

He estado mirando el comando ordenar pero solo he podido encontrar la clasificación vertical, no horizontal. Me complace utilizar cualquier herramienta, cualquier ayuda es apreciada. ¡Gracias!

Creemos una función para transponer un archivo (las filas se convierten en columnas y las columnas se convierten en filas):

 transpose () { awk '{for (i=1; i<=NF; i++) a[i,NR]=$i; max=(max 

Esto simplemente carga todos los datos en una matriz bidimensional a[line,column] y luego la vuelve a imprimir como a[column,line] , de modo que transpone la entrada dada. El contenedor transpose () { } se usa para almacenarlo como una función bash. Solo tiene que copiar y pegarlo en su shell (o en ~/.bashrc si desea que sea una función permanente, disponible cada vez que abre una sesión).

Luego, al usarlo, podemos resolver el problema fácilmente utilizando sort -n -k2 : sort numérico basado en la columna 2. Luego, transponer de nuevo.

 $ cat a | transpose | sort -n -k2 | transpose john sarah mark 5 10 20 zxy 

En caso de que quiera tener un buen formato como resultado final, solo canalice a la column siguiente manera:

 $ cat a | transpose | sort -n -k2 | transpose | column -t john sarah mark 5 10 20 zxy 

Paso a paso:

 $ 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 

Viniendo de una pregunta duplicada , esto ordenaría las columnas por la primera fila:

 #!/bin/bash input="$1" order=$((for i in $(head -1 $input); do echo $i; done) | nl | sort -k2 | cut -f1) grep ^ $input | (while read line do read -a columns <<< "${line%"${line##*[![:space:]]}"}" orderedline=() for i in ${order[@]} do orderedline+=("${columns[$i - 1]}") done line=$(printf "\t%s" "${orderedline[@]}") echo ${line:1} done) 

Para ordenar por segunda fila, reemplace head -1 $input con head -2 $input | tail -1 head -2 $input | tail -1 . Si la ordenación debe ser numérica, ponga sort -n -k2 lugar de sort -k2 .

Un buen trazador de líneas hace el trabajo:

perl -ane '$,=" "; print sort @F; print "\n";' file

Lo encontré aquí: http://www.unix.com/unix-for-advanced-and-expert-users/36039-horizontal-sorting-lines-file-sed-implementation.html