Ordene los datos en orden descendente de la primera columna, para valores iguales, use la segunda columna en orden ascendente

22

Permíteme aclarar:

Supongamos que tengo algunas palabras clave con frecuencia de uso:

12 Hi
7  Hash
7  C++  
9  Superuser
17 Stackoverflow
9  LaTeX  
42 Life
9  Ubuntu

Lo que quiero es ordenar estos datos en función de la frecuencia en orden descendente y si hay algunos valores iguales, debería usar la segunda columna en orden ascendente.

sort -n -r foo.txt

¿La primera parte pero luego la segunda columna también son reversed:

42 Life
17 Stackoverflow
12 Hi
9  Ubuntu
9  Superuser
9  LaTeX  
7  Hash
7  C++

¿Cómo puedo lograr los siguientes resultados?

42 Life
17 Stackoverflow
12 Hi
9  LaTeX  
9  Superuser
9  Ubuntu
7  C++ 
7  Hash

Creo que tengo que usar -kargumentos, ¡pero no puedo entender cómo!

Quiero saber cómo se puede hacer esto usando únicamente el sortcomando de bash. Sin embargo, si no es posible lograr esto solo mediante sort, otros comandos deberían ser compatibles con el shell Bourne.

Pouya
fuente
[Algo OT]: aunque es equivalente para estos datos en particular, usar la -gopción GNU-sort (numérico general) en lugar de -nlas comparaciones numéricas es más seguro: funciona correctamente tanto para coma flotante como para enteros.
arielf

Respuestas:

32

Especifique las claves de clasificación por separado con los criterios:

sort -k1,1nr -k2,2 inputfile

Esto especifica que la primera clave se ordena numéricamente en orden inverso, mientras que la segunda se ordena según el orden de clasificación predeterminado .

Citando del orden POSIX :

-k keydef

El argumento keydef es una definición de campo de clave de clasificación restringida. El formato de esta definición es:

inicio_campo [ tipo ] [ , fin_campo [ tipo ]]

donde field_start y field_end definen un campo clave restringido a una parte de la línea (consulte la sección DESCRIPCIÓN EXTENDIDA), y type es un modificador de la lista de caracteres 'b', 'd', 'f', 'i', ' n ',' r '. El modificador 'b' se comportará como la -bopción, pero solo se aplicará al field_start o field_end al que está adjunto. Los otros modificadores se comportarán como las opciones correspondientes, pero se aplicarán solo al campo clave al que están adjuntos; Tendrán este efecto si se especifica con field_start , field_end o ambos., ninguna opción se aplicará a ninguno de los dos. Las implementaciones deberán soportar al menos nueve apariciones de la -kopción, que serán significativas en el orden de la línea de comando. Si no -kse especifica ninguna opción, se utilizará una clave de clasificación predeterminada de toda la línea.

Cuando hay múltiples campos de clave, las claves posteriores se compararán solo después de que todas las claves anteriores se comparen igual. Excepto cuando el -use especifica la opción, las líneas que de otra manera se comparan iguales se ordenarán como si ninguna de las opciones -d, -f, -i, -n, o -kestaban presentes (pero con -r todavía en efecto, si se especificó) y con todos los bytes en las líneas significativas a la comparación. El orden en el que se escriben las líneas que todavía comparan igual no está especificado.

Esto produciría:

42 Life
17 Stackoverflow
12 Hi
9  LaTeX
9  Superuser
9  Ubuntu
7  C++
7  Hash
devnull
fuente
Gracias. Hizo el truco. ¡Hay que esperar 10 minutos para aceptar!
Pouya
@StephaneChazelas Gracias por señalarlo; actualizado la referencia.
devnull