Ordenar según la tercera columna


132

Me enfrento a un enorme archivo de 4 columnas. Me gustaría mostrar el archivo ordenado en stdout según su tercera columna:

cat myFile | sort -u -k3

¿Es eso suficiente para realizar el truco?


44
Tenga en cuenta que puede escribir esto como sort -u -k3 < myFile.
gerrit

66
Como sort -u -k3 myFile, incluso
Sebastian Graf

Respuestas:


168
sort -k 3,3 myFile

sería mostrar el archivo ordenado por la 3 rd columna asumiendo las columnas están separadas por secuencias de espacios en blanco (SPC ASCII y caracteres de tabulación en la configuración regional POSIX / C), de acuerdo con el orden de clasificación definida por la localización actual.

Tenga en cuenta que los espacios en blanco iniciales se incluyen en la columna (el separador predeterminado es la transición de un espacio en blanco a un espacio en blanco), que puede marcar la diferencia en los entornos locales donde no se ignoran los espacios para fines de comparación, use la -bopción para ignorar los espacios en blanco principales.

Tenga en cuenta que es completamente independiente del shell (todos los shells analizarían esa línea de comando de la misma manera, los shells generalmente no tienen el sortcomando incorporado).

-k 3consiste en ordenar la parte de las líneas que comienzan con la columna (incluidos los espacios en blanco iniciales ). En la configuración regional C, debido a que el espacio y los caracteres de tabulación se ubican antes que todos los caracteres imprimibles, eso generalmente le dará el mismo resultado que -k 3,3(excepto para las líneas que tienen un tercer campo idéntico),

-ues retener solo una de las líneas si hay varias que se clasifican de forma idéntica (es donde la clave de clasificación se ordena de la misma manera (eso no es necesariamente lo mismo que ser igual ))

cates el comando para con cat enate. No lo necesitas aquí.

Si las columnas están separadas por otra cosa, necesita la -topción para especificar el separador.

Archivo de ejemplo dado a

$ cat a
a c c c
a b ca d
a b  c e
a b c d

Con -u -k 3:

$ echo $LANG
en_GB.UTF-8

$ sort -u -k 3 a
a b ca d
a c c c
a b c d
a b  c e

Las líneas 2 y 3 tienen la misma tercera columna, pero aquí la clave de clasificación es desde la tercera columna hasta el final de la línea, por lo que -uretiene ambas. ␠ca␠dordena antes ␠c␠cporque los espacios se ignoran en la primera pasada en mi configuración regional, cadordena antes cc.

$ sort -u -k 3,3 a
a b c d
a b  c e
a b ca d

Arriba solo se retiene uno para aquellos donde está la 3ra columna ␠c. Observe cómo ␠␠cse retiene el que tiene (2 espacios iniciales).

$ sort -k 3 a
a b ca d
a c c c
a b c d
a b  c e
$ sort -k 3,3 a
a b c d
a c c c
a b  c e
a b ca d

Vea cómo se invierte el orden de a b c dy a c c c. En el primer caso, porque ␠c␠cordena antes ␠c␠d, en el segundo caso porque la clave de clasificación es la misma ( ␠c), la comparación de último recurso que compara las líneas en las posiciones completas a b c dantes a c c c.

$ sort -b -k 3,3 a
a b c d
a b  c e
a c c c
a b ca d

Una vez que ignoramos los espacios en blanco, la clave de clasificación para las primeras 3 líneas es la misma ( c), por lo que se ordenan según la comparación de último recurso.

$ LC_ALL=C sort -k 3 a
a b  c e
a c c c
a b c d
a b ca d
$ LC_ALL=C sort -k 3,3 a
a b  c e
a b c d
a c c c
a b ca d

En la configuración regional de C, se ␠␠cordena antes, ␠cya que solo hay una pasada allí donde los caracteres (luego bytes individuales) se ordenan según su valor de punto de código (donde el espacio tiene un punto de código menor que c).


las columnas están blankseparadas que pueden incluir otros caracteres además del espacio y la pestaña según la configuración regional.
jfs

1
Niza, +1. ¿Podría explicar qué 3,3hace? ¿Por qué no solo 3?
terdon

@terdon, vea la descripción ampliada con ejemplos.
Stéphane Chazelas

@JFSebastian, tienes razón, la respuesta actualizada.
Stéphane Chazelas

Ah, para que solo se ordene en el 3er, no el resto de la línea, gracias.
terdon

4

Si entiende "columna" como en un archivo de texto (cuarto carácter), entonces sí, su solución debería funcionar (o incluso sort -u -k3 myFilepermitir sortrealizar algunas magias de ahorro de memoria con acceso aleatorio). Si entiende "columna" como en la base de datos: una entidad completa de datos seguida de un separador y un ancho de columna variable, necesitará algo más elegante, por ejemplo, esto ordena ls -l por tamaño

      ls -l |awk '{print $5 " " $0;}'| sort -n | cut -d " " -f 2-

(que es equivalente a trivial ls -lSpero sirve muy bien el ejemplo).


55
No, por defecto ordenar columnas están en blanco separado, no son las columnas de caracteres, para ordenar en la columna de caracteres tercero, la sintaxis sería: sort -k 1.3,1.3. ls -l | sort -k5,5nordenar según el tamaño.
Stéphane Chazelas

La awksolución es exactamente lo que necesitaba: fácil de modificar para ajustarse a los requisitos de clasificación complejos
jchook,

2
sort -g -k column_number 

es el comando correcto para ordenar cualquier lista que tenga caracteres numéricos usando una columna específica


1
El uso de -k ya se cubrió bastante bien, por lo que sería útil si explicara cómo este comando es diferente o mejor. Tal vez también podría incluir números de columna reales para abordar la pregunta real del OP.
Jeff Schaller

Esto me llevó a usar las páginas man: p "-g, --general-numeric-sort, compare según el valor numérico general", que era lo que necesitaba en mi caso.
Joels


0
$ sort -k 1.3,1.3 myfile

Clasificará su archivo myfile en la tercera columna si su archivo no tiene ningún separador.

$ cat myfile 
ax5aa 
aa3ya 
fg7ds 
pp0dd 
aa1bb

$ sort -k 1.3,1.3 myfile 
pp0dd 
aa1bb
aa3ya 
ax5aa 
fg7ds 

página man de tipo:

[...] -k, --key = POS1 [, POS2] iniciar una clave en POS1 (origen 1), finalizarla en POS2 (final de línea predeterminado) [...] POS es F [.C] [ OPTS], donde F es el número de campo y C la posición del personaje en el campo; ambos son de origen 1. Si ni -t ni -b está en efecto, los caracteres en un campo se cuentan desde el comienzo del espacio en blanco anterior. OPTS es una o más opciones de pedido de una sola letra, que anulan las opciones de pedido global para esa clave. Si no se proporciona ninguna clave, use la línea completa como clave.

Con --key = 1.3,1.3, dijiste que solo hay un campo (toda la línea) y que estás comparando la posición del tercer carácter de este campo.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.