2012-07-12 13 views
5

que hay que solucionar algunos datos con UNIX especie, pero no puedo averiguar exactamente la sintaxis correcta, los datos se pareceUNIX tipo para 2 campos de orden numérico

3.9.1 Step 10: 
3.9.1 Step 20: 
3.8.10 Step 20: 
3.10.2 Step 10: 
3.8.4 Step 90: 
3.8.4 Step 100: 
3.8.4 Step 10: 

quiero solucionarlo utilizando en primer lugar la mayor número, luego el número de paso, por ej. los datos ordenados arriba se verían así.

3.8.4 Step 10: 
3.8.4 Step 90: 
3.8.4 Step 100: 
3.8.10 Step 20: 
3.9.1 Step 10: 
3.9.1 Step 20: 
3.10.2 Step 10: 

he encontrado la manera de clasificar por primera serie en este sitio:

sort -t. -k 1,1n -k 2,2n -k 3,3n 

pero estoy luchando por ahora ordenar por la tercera serie de columnas de paso sin perturbar el primero ordenar

+0

Cuando trato de la línea de órdenes que le dio en sus datos de la muestra, se produce la respuesta dijiste que querías ... – jacobm

+0

@jacobm, revisa la tercera columna, está ordenada incorrectamente – Steve

+0

Estoy en solaris 10 si eso hace la diferencia, y sí tercera columna todavía no está bien – jdex

Respuesta

2

Hay un artículo fascinante sobre la reingeniería de Unix sort ('Teoría y práctica en la construcción de una rutina de clasificación de trabajo', JP Linderman, AT & T Bell Labs Tech Journal, octubre de 1984) que, desafortunadamente, no está disponible en Internet. , AFAICT (Lo miré hace un año o algo así y no lo encontré; volví a mirar en este momento y puedo encontrar referencias a él, pero no el artículo en sí). Entre otras cosas, el artículo demostró que para Unix sort, el tiempo de comparación supera con creces el costo de mover datos (no es muy sorprendente si se considera que la comparación tiene que comparar campos determinados por fila, pero mover 'datos' es simplemente una cuestión de cambiar punteros alrededor). Una conclusión de esto fue que recomiendan hacer lo que sugiere danfuzz; mapeo de claves para facilitar las comparaciones. Mostraron que incluso una solución con guiones simple podría ahorrar tiempo en comparación con hacer que el trabajo de clasificación sea realmente difícil.

Por lo tanto, podría pensar en términos de usar un carácter que es poco probable que aparezca en el archivo de datos de forma natural (como Control-A) como el separador de campo clave.

sed 's/^\([^.]*\)[.]\([^.]*\)[.]\([^ ]*\) Step \([0-9]*\):.*/\1^A\2^A\3^A\4^A&/' file | 
sort -t'^A' -k1,1n -k2,2n -k3,3n -k4,4n | 
sed 's/^.*^A//' 

El primer comando es el más difícil. Identifica los 4 campos numéricos, y los saca separados por el carácter elegido (escrito ^A arriba, mecanografiado como Control-A), y luego muestra una copia de la línea original. El orden entonces funciona en los primeros cuatro campos numéricamente, y los comandos finales sed se quitan del frente de cada línea hasta e incluyendo el último Control-A, devolviéndole la línea original nuevamente.

+0

relacionada? http://cs.fit.edu/~pkc/classes/writing/samples/bentley93engineering.pdf –

+0

@FrankComputer: relacionado, definitivamente, y cita a Linderman. Pero no es lo mismo. Ver también [Elegir un pivote para una QuickSort] (http://stackoverflow.com/questions/164163/choosing-a-pivot-for-quicksort/164183#164183), donde menciono el papel de Bentley sobre el que pregunta y algunos otros. –

+0

Pude obtener una vista previa breve aquí: http://books.google.com/books?id=Hy62AAAAIAAJ&q=Linderman#search_anchor –

2

¿Qué hay de la transformación de la Step y : en el camino en sort, y luego la transformación posterior? Creo que esta obtiene los resultados que buscas para: (. Sólo mediante cat aquí con fines expositivos Si es sólo un archivo normal, entonces podría ser pasado a la primera sed.)

cat your-file.txt \ 
    | sed -e 's/ Step \(.*\):$/.\1/g' \ 
    | sort -t. -k1,1n -k2,2n -k3,3n -k4,4n \ 
    | sed -e 's/\(.*\)\.\(.*\)$/\1 Step \2:/g' 

+0

Esperaba una solución más ordenada que utilizara únicamente el género, pero creo que esto también funcionaría. +1 arriba verá si alguien más conoce una forma diferente – jdex

1

ACTUALIZADO:

Esto generará la salida especificada:

sed 's/Step /Step./' data|sort -t. -n -k1,1 -k2,2 -k3,3 -k4|sed 's/Step./Step /' 

resultado:

3.8.4 Step 10: 
3.8.4 Step 90: 
3.8.4 Step 100: 
3.8.10 Step 20: 
3.9.1 Step 10: 
3.9.1 Step 20: 
3.10.2 Step 10: 

El reto de este tipo es que los campos de clasificación se definen por ambos '.' (para los números de versión) y el d espacios en blanco predeterminados (para los números del Paso). No puede especificar varios/diferentes separadores de campo para el mismo comando de clasificación. La combinación de varios géneros con diferentes separadores de campo no produjo el resultado correcto.

Esta solución funciona mediante la sustitución del espacio en blanco después de que el campo Steptemporalmente con un '.' de modo que todos los campos de clasificación se pueden separar con el mismo carácter ('.'). Una vez hecho el ordenamiento, el '.' se reemplaza con un espacio en blanco nuevamente.

+0

aunque no está ordenado por la columna de pasos ... – jdex

+0

@jdex Encontré una solución que creo, por favor vea si esta es una respuesta aceptable para su problema. – Levon

+0

+1, realmente quería evitar modificar los datos porque lo que proporcioné no es el conjunto de datos completo.Hay una descripción de cadena de cada paso (a veces también contiene "Paso"). está empezando a parecer que no hay otra manera, aunque – jdex

2

Esto podría funcionar para usted:

sort -k3,3n file | sort -nst. -k1,1 -k2,2 -k3,3 

o una muy dudoso:

sort -nt. -k1,1 -k2,2 -k3,3 -k3.7 file 

El primero utiliza dos tipos:

  1. sort -k3,3n ordena por pasos
  2. sort -nst. -k1,1 -k2,2 -k3,3 ordena por números principales pero mantiene el paso o der

Las segundas obras, pero sólo si la tercera mayor número se mantiene por debajo de 100.

o tal vez:

sed 's/ /./2' file | sort -nt. -k1,1 -k2,2 -k3,3 -k4,4 | sed 's/\./ /3' 
+0

Creo que el primero funcionaría, pero la versión de tipo que estoy usando en Solaris 10 no tiene la opción -s. – jdex

+0

@jdex lo siento, supongo que '-s' es una función de GNU. La solución 'sed' puede ayudar – potong