GNU/Linux >> Tutoriales Linux >  >> Linux

¿Intenta ordenar en dos campos, el segundo y luego el primero?

Estoy tratando de ordenar en varias columnas. Los resultados no son los esperados.

Aquí están mis datos (personas.txt):

Simon Strange 62
Pete Brown 37
Mark Brown 46
Stefan Heinz 52
Tony Bedford 50
John Strange 51
Fred Bloggs 22
James Bedford 21
Emily Bedford 18
Ana Villamor 44
Alice Villamor 50
Francis Chepstow 56

Lo siguiente funciona correctamente:

bash-3.2$ sort -k2 -k3 <people.txt                                                                                                                    
Emily Bedford 18                                                                                                                                      
James Bedford 21                                                                                                                                      
Tony Bedford 50                                                                                                                                       
Fred Bloggs 22                                                                                                                                        
Pete Brown 37                                                                                                                                         
Mark Brown 46                                                                                                                                         
Francis Chepstow 56                                                                                                                                   
Stefan Heinz 52                                                                                                                                       
John Strange 51                                                                                                                                       
Simon Strange 62                                                                                                                                      
Ana Villamor 44                                                                                                                                       
Alice Villamor 50

Pero lo siguiente no funciona como se esperaba:

bash-3.2$ sort -k2 -k1 <people.txt                                        
Emily Bedford 18                                                                                                                                      
James Bedford 21                                                                                                                                      
Tony Bedford 50                                                                                                                                       
Fred Bloggs 22                                                                                                                                        
Pete Brown 37                                                                                                                                         
Mark Brown 46                                                                                                                                         
Francis Chepstow 56                                                                                                                                   
Stefan Heinz 52                                                                                                                                       
John Strange 51                                                                                                                                       
Simon Strange 62                                                                                                                                      
Ana Villamor 44                                                                                                                                       
Alice Villamor 50

Estaba tratando de ordenar por apellido y luego por nombre, pero verán que los Villamor no están en el orden correcto. Tenía la esperanza de ordenar por apellido y luego, cuando los apellidos coincidieran, ordenar por nombre.

Parece que hay algo acerca de cómo debería funcionar esto que no entiendo. Por supuesto, podría hacerlo de otra manera (usando awk), pero quiero entender la ordenación.

Estoy usando el shell Bash estándar en Mac OS X.

Respuesta aceptada:

Una especificación clave como -k2 significa tener en cuenta todos los campos desde el 2 hasta el final de la línea. Entonces Villamor 44 termina antes de Villamor 50 . Dado que estos dos no son iguales, la primera comparación en sort -k2 -k1 es suficiente para discriminar estas dos líneas, y la segunda clave de clasificación -k1 no se invoca. Si los dos Villamor hubieran tenido la misma edad, -k1 habría causado que se clasificaran por nombre.

Para ordenar por una sola columna, use -k2,2 como especificación clave. Esto significa usar los campos del #2 al #2, es decir, solo el segundo campo.

sort -k2 -k3 <people.txt es redundante:es equivalente a sort -k2 <people.txt . Para ordenar por apellidos, luego nombres y luego edad, ejecute el siguiente comando:

sort -k2,2 -k1,1 <people.txt

o equivalentemente sort -k2,2 -k1 <people.txt ya que solo existen estos tres campos y los separadores son los mismos. De hecho, obtendrá el mismo efecto de sort -k2,2 <people.txt , porque sort usa toda la línea como último recurso cuando todas las claves en un subconjunto de líneas son idénticas.

Relacionado:¿Cómo buscar texto en un archivo y mostrar el párrafo que tiene el texto?

También tenga en cuenta que el separador de campo predeterminado es la transición entre un espacio en blanco y otro que no está en blanco, por lo que las claves incluirán los espacios en blanco iniciales (en su ejemplo, para la primera línea, la primera clave será "Emily" , pero la segunda clave " Bedford" . Agregue el -b opción para eliminar esos espacios en blanco:

sort -b -k2,2 -k1,1

También se puede hacer por tecla agregando b indicador al final de la especificación de inicio clave:

sort -k2b,2 -k1,1 <people.txt

Pero algo a tener en cuenta:tan pronto como agregue una de esas banderas a la especificación clave, las banderas globales (como -n , -r …) ya no se aplican a ellos, por lo que es mejor evitar mezclar banderas por tecla y banderas globales.


Linux
  1. ¿Cómo seleccionar la primera aparición entre dos patrones, incluyéndolos?

  2. ¿Cómo comparar dos archivos y luego agregar una línea que no coincida parcialmente?

  3. ¿Ordenar parte de un archivo?

  4. Lum:¿reemplazar valores comunes en dos archivos según la primera columna?

  5. Dos pantallas X, ¿cómo obtener un administrador de ventanas en la segunda pantalla?

¿Cambiar a una segunda sesión X mata a la primera?

¿Ordenar por valor hexadecimal?

¿Ordenar salida por columna?

¿Archivo de ordenación de shell de Linux de acuerdo con la segunda columna?

Comparando dos listas desordenadas en Linux, enumerando el único en el segundo archivo

¿Cómo cambio la primera y la segunda transmisión de audio en un MKV en un sistema basado en Linux?