2008-12-10 22 views
113

Tengo archivos potencialmente grandes que deben ordenarse por claves 1-n. Algunas de estas claves pueden ser numéricas y algunas de ellas podrían no serlo. Este es un archivo columnar de ancho fijo por lo que no hay delimitadores.Ordenar varias claves con clasificación de Unix

¿Hay una buena manera de hacer esto con Unix? Con una tecla es tan simple como usar '-n'. He leído la página de manual y he buscado brevemente en Google, pero no he encontrado un buen ejemplo. ¿Cómo podría lograr esto?

Nota: He descartado Perl debido al potencial del tamaño del archivo. Sería un último recurso.

+0

una o dos líneas de datos de ejemplo sería realmente útil para la creación de línea de comando de ejemplo. Además, ¿las teclas "1-n" significan que debe ordenar por un número variable de teclas? Hacer eso sin secuencias de comandos va a ser divertido ... –

+0

Tengo un envoltorio PHP alrededor del comando de ordenación para habilitar la función 1-n. –

Respuesta

56

Utilice la opción -k (o --key=POS1[,POS2]). Puede aparecer varias veces y cada tecla puede tener opciones globales (como n para el tipo numérico)

+6

En la página de manual de clasificación: "POS es F [.C] [OPTS], donde F es el número de campo y C la posición del carácter en el campo; ambos son origen 1." Consulte la página de manual para obtener la documentación completa. –

+37

También vea la respuesta de andras si no quiere volverse loco. – ron

+1

Ambos comentarios anteriores son precisos y aditivos. Gracias, señores. –

85

La opción -k es lo que desea.

-k 1.4,1.5n -k 1.14,1.15n 

Se utiliza de posiciones de carácter 4-5 en el primer campo (es todo un campo de ancho fijo) y clasificar numéricamente como la primera clave.

La segunda clave sería los caracteres 14-15 en el primer campo también.

(editar)

Ejemplo (todo lo que tengo es de DOS/cygwin práctico):

dir | \cygwin\bin\sort.exe -k 1.4,1.5n -k 1.40,1.60r 

de los datos:

12/10/2008 01:10 PM   1,564,990 outfile.txt 

Ordena la lista de directorios por número de meses (POS 4-5) numéricamente, y luego por nombre de archivo (pos 40-60) en reversa. Como no hay pestañas, todo el campo 1 se ordena.

+0

Es solo un campo si no hay espacios en blanco en los datos de entrada. Sin embargo, tu ejemplo es útil. –

+0

Corrección: si no hay/pestañas/en los datos de entrada. En el resultado del comando 'dir' de DOS, no hay pestañas. –

+0

Los ejemplos sobre cómo usar las opciones (numérico, reverso) son extremadamente útiles, ya que es casi imposible averiguar cómo usarlos desde la página de manual y las otras respuestas no lo mencionaron. Ojalá pudiera +2 por esto. ;) – msb

10

que creen en su caso algo así como

sort [email protected] -k1.1,1.4 -k1.5,1.7 ... <inputfile 

va a funcionar mejor. @ es el separador de campo, asegúrese de que sea un personaje que no aparece en ninguna parte. entonces su entrada se considera como que consiste en una columna.

Editar: Aparentemente clintp ya dio una respuesta similar, lo siento. Como él señala, las banderas 'n' y 'r' se pueden agregar a cada opción -k ....

262

Tenga cuidado sin embargo:

Si desea ordenar el archivo principalmente por el campo 3, y en segundo lugar por el campo 2 no desea esto:

sort -k 3 -k 2 < inputfile 

desea que esta vez:

sort -k 3,3 -k 2,2 < inputfile 

El primero ordena el archivo por la cadena desde el principio del campo 3 hasta el final de la línea (que es potencialmente único).

-k, --key=POS1[,POS2]  start a key at POS1 (origin 1), end it at POS2 
          (default end of line) 
+19

Esto es bastante importante, ¡gracias! – ron

+6

Cambio de vida. Gracias. – notJim

+2

¡Vaya! Ahora tengo que arreglar un script porque antes solo veía la primera respuesta arriba ... es bueno que aún no haya dependido de la salida del script .... – Wildcard

5

Tenga en cuenta que se pueden también desee estabilizar el tipo con el interruptor -s, de manera que las líneas de igual rango mantienen su orden relativo original en la salida también.

2

Solo quiero agregar algunos consejos, al usar la ordenación, tenga cuidado con su configuración regional que afecta el orden de la comparación de claves. Usualmente uso explícitamente LC_ALL = C para hacer que lo local sea lo que quiero.

+0

LC_ALL = C también puede dar lugar a una gran aceleración. –

16

Aquí está uno para ordenar varias columnas en un archivo csv por orden numérico y diccionario, columnas 5 y después de que el diccionario de fin

~/test>sort -t, -k1,1n -k2,2n -k3,3d -k4,4n -k5d sort.csv 
1,10,b,22,Ga 
2,2,b,20,F 
2,2,b,22,Ga 
2,2,c,19,Ga 
2,2,c,19,Gb,hi 
2,2,c,19,Gb,hj 
2,3,a,9,C 

~/test>cat sort.csv 
2,3,a,9,C 
2,2,b,20,F 
2,2,c,19,Gb,hj 
2,2,c,19,Gb,hi 
2,2,c,19,Ga 
2,2,b,22,Ga 
1,10,b,22,Ga 

Nota del -k1,1n significa partida numérico en la columna 1 y terminando a las columna 1. Si hubiera hecho a continuación, tendría la columna concatenada 1 y 2 haciendo 1,10 ordenan como 110

~/test>sort -t, -k1,2n -k3,3 -k4,4n -k5d sort.csv 
2,2,b,20,F 
2,2,b,22,Ga 
2,2,c,19,Ga 
2,2,c,19,Gb,hi 
2,2,c,19,Gb,hj 
2,3,a,9,C 
1,10,b,22,Ga 
+1

Esta es la mejor respuesta porque muestra cómo usar diferentes interruptores para diferentes columnas – xaxa

Cuestiones relacionadas