Friday, January 12, 2007

Obtener los N máximos valores.

Hoy me topé con el problema de encontrar los N primeros valores de la columna 10, de una información que se encontraba en texto plano separado por comas.

Sé que la solución más fácil (pero no necesariamente la más óptima) sería utilizar algo como este oneliner:

 cut -d, -f10 archivo | sort -rn | head -20

Pero como siempre me interesa hacerme la vida un poco más difícil, pensé en hacerlo en AWK, para lo cual utilicé el siguiente oneliner:

 awk -F, -v T=20 '{ V=int($10); C=0; for(i=0;i<T && C==0;i++)if(V>F[i]){ C++; for(j=T-1;j>i;j--) F[j]=F[j-1]; F[i]=V } };
END{ for(i=0;i<T;i++) print F[i] }'

Luego de tomar algunos tiempos en segundos, verifiqué cuál era el método más rápido:

awk: 294s 296s 296s
cut+sort: 91s 88s 91s

Si, el burdo método del cut+sort es el más rápido, pero aún así prefiero el método AWK, el porqué es muy simple: awk me obliga a pensar,de manera lógica, acerca de cómo debo atacar el problema.

Cut y sort, no me obligan a pensar nada, ya están allí y simplemente tendría que usarlos, pero para usar cosas que no me obligan a pensar tengo más que de sobra.

BTW: el archivo mide algo más de 300mb comprimido, y los tiempos aquí incluyen la decompresión en línea. El número de registros es de algo más de 13 millones, la máquina obviamente no es una XT (como muchos pensarían de mí).

BTW2: acabo de recordar que tengo que utilizar htmlentities para publicar el código con comparaciones "menor que" o "mayor que".

--
KIT

Labels:

1 Comments:

Blogger Herr Hauptmann said...

Ya que hablas de shell script, acá uno muy útil, el que te permite mostrar en qué archivos se encuentra tal o cual cadena de texto:

"find . -exec grep -l 'CADENA_AQUI' {} \;"

Esto lo puedes combinar para borrar esos archivos, o moverlos, etc..

Lo de tu comando 'awk' no se me hubiera ocurrido ni en el más alocada de mis alucinaciones :S

February 24, 2009 at 8:17 AM  

Post a Comment

<< Home