juan 25
maria 37
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
salva escribiste:Como te comenta explorer, si tienes memoria suficiente para leer el archivo pequeño en un hash, esa es la solución más fácil y rápida.
Si no, la solución clásica a este problema es ordenar los dos ficheros en disco por el campo clave (usando la utilidad sort o el módulo Sort::External, por ejemplo) para luego leer los dos ficheros ordenados en paralelo buscando coincidencias.
Bueno, actualmente hay servidores con 32Gb o más de memoria, así que la limitación es el dineroStoner escribiste:El problema, como ya os he dicho, es que la RAM no me da para meter en un hash un archivo entero (bueno, solo la primera columna). Cuando corro el script al rato el ordenador se ralentiza muchísimo y directamente se congela todo, incluyendo el ratón. Que me quedo sin memoria, vamos.
Ya lo dice salva: recorriendo las líneas de los archivos en paralelo.Stoner escribiste:El problema es que ambos archivos no tienen por qué contener el mismo número de líneas, ni en cada línea tiene que haber los mismo campos. Quiero decir que no entiendo cómo podría ayudarme a extraer las líneas únicas de uno de los archivos ordenando ambos.
En este ejemplo, estamos suponiendo que tenemos que imprimir las líneas del archivo 2 si no hay coincidencia con las del 1.Stoner escribiste:Archivo 1 ordenado:Using text Syntax Highlighting
Archivo 2 ordenado:
explorer escribiste:
- Entonces, empezamos leyendo una línea de cada archivo y sacamos las claves: "juan" y "maria".
- Como la clave "juan" es menor que la de "maria", debemos seguir leyendo líneas del archivo 1 hasta que las claves "alcancen" a "maria".
- Leemos la siguiente línea de archivo 1 y tenemos "maria". Como esta clave es idéntica en los dos archivos, no nos interesa, así que leemos una nueva línea de cada archivo.
- Leemos las siguientes, y tenemos "pepe" y "Oswaldo".
- Como "pepe" es superior a "Oswaldo", quiere decir que no hemos encontrado ninguna clave en el archivo 1 que coincida con "Oswaldo", y como los archivos están ordenados, no encontraremos ninguno más en el resto del archivo 1, así que la clave del archivo 2 es única: imprimimos la línea de "Oswaldo".
- Leemos la siguiente línea de archivo 2 y tenemos "pepe".
- Lo mismo que antes, coinciden las claves, así que el siguiente paso es leer las líneas siguientes de los dos archivos.
- En este caso ya hemos llegado al final, así que damos por termino el proceso. Si hubieran quedado líneas por leer del segundo archivo, serían líneas únicas, así que las sacaríamos directamente.
explorer escribiste:60 millones de líneas no es nada...
¿Cómo son de grandes las claves que estás guardando en el hash?
Para resolver por la segunda forma, primero debes resolver cómo poder ordenar los dos archivos, de forma alfanumérica. Es muy posible que ni siquiera puedas hacerlo con otro programa Perl.
Prueba a ver con el comando sort del sistema...
Una forma de ordenar un archivo grande es:
* leer el archivo línea por línea
* según la primera letra de la línea, grabamos la línea en otro archivo que almacena todas las líneas que comienzan por esa letra
Al final tenemos tantos archivos como letras, mucho más pequeños que el original. Ahora puedes abrirlos uno por uno y ordenarlos alfabéticamente (o usar sort del sistema). Y una vez que están ordenados, ya solo queda leerlos en secuencia para generar un único archivo, pero esta vez ya estará ordenado.
Hacer lo mismo con el otro archivo, y ya se puede iniciar el segundo procedimiento de búsqueda de claves inexistentes.
P.D. ¿No estarás usando Windows, verdad? Esa puede ser una buena explicación de por qué te quedas sin memoria.
Claro: dada una clave en un archivo, deberías buscarla en todos los trozos del otro archivo. No vale con mirar trozo por trozo.Stoner escribiste:Lo que había hecho era una solución como la del código que he escrito arriba pero partiendo uno de los archivos en trozos (para que el hash que se guarda en memoria no pese tanto), y correr scripts de forma secuencial.
Es decir, partía el archivo_1 en fragmentos mas pequeños, obtenía las líneas con columna única del archivo_2 respecto al primer trozo del archivo_1, y vuelvo a hacer lo mismo sucesivamente comparando el archivo resultado con el siguiente trozo.
El problema era, aún no sé por qué, no me daba el resultado esperado.
La ventaja de ordenarles es que eliminas el problema gordo de hacer un doble bucle.Stoner escribiste:A partir de determinada línea del primer archivo se saltaba resultados. Es algo parecido a lo que me indicas con hacer archivos más pequeños ordenados alfabéticamente. Por eso intenté hacerlo todo "de golpe", sin partir el primer archivo y metiéndolo todo en un hash.
Dentro de /home, ejecuta el comando du|sort -n y así sabrás cuáles son los directorios más ocupados.Stoner escribiste:Uso Linux y no sé qué pasa con mi sistema que me quedo sin espacio en /home. El analizador de uso del disco me dice que me quedan 46 GB de espacio libre en /home, pero sin embargo me aparece el mensaje: «El volumen <<home>> solo tiene 459,8 MB de espacio en disco libre».
Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 17 invitados