Tengo un proceso embarazosamente paralelo que crea una gran cantidad de archivos casi (pero no completamente) idénticos. ¿Hay alguna manera de archivar los archivos "sobre la marcha", para que los datos no consuman más espacio del necesario?
El proceso en sí mismo acepta parámetros de línea de comandos e imprime el nombre de cada archivo creado para stdout. Lo invoco con el parallel --gnuque se encarga de distribuir la entrada (que proviene de otro proceso) y recopilar la salida:
arg_generating_process | parallel --gnu my_process | magic_otf_compressor
EJEMPLO SIMPLE para la primera parte de la tubería en bash:
for ((f = 0; $f < 100000; f++)); do touch $f; echo $f; done
¿Cómo podría magic_otf_compressorverse? Se supone que debe tratar cada línea de entrada como nombre de archivo, copiar cada archivo a un .tararchivo comprimido (¡el mismo archivo para todos los archivos procesados!) Y luego eliminarlo. (En realidad, debería ser suficiente para imprimir el nombre de cada archivo procesado, otro | parallel --gnu rmpodría encargarse de eliminar los archivos).
¿Existe alguna herramienta de este tipo? No estoy considerando comprimir cada archivo individualmente, esto desperdiciaría demasiado espacio. He investigado archivemount(mantendrá el sistema de archivos en la memoria -> imposible, mis archivos son demasiado grandes y demasiados) y avfs(no pude hacer que funcione junto con FUSE). ¿Qué me he perdido?
Estoy a un paso de hackear una herramienta así, pero alguien debe haberlo hecho antes ...
EDITAR : Básicamente creo que estoy buscando un front-end stdin para libtar(a diferencia del front-end de la línea de comandos tarque lee argumentos de, bueno, la línea de comandos).
fuente

Respuestas:
Parece que
tarquiere saber todos los nombres de archivo por adelantado. Entonces es menos sobre la marcha y más después de la marcha.cpiono parece tener ese problema:fuente
tarel código para ver que hay una función que devuelve el siguiente nombre de archivo para ser procesado, lo que me hizo leer la documentación nuevamente. - Entonces, ¿stdoutse dirige algzipproceso a través de la sustitución del proceso ystderrse redirige astdoutcuál se procesa en el siguiente paso en la tubería?tarlee la lista de archivos primero, usando el ejemplo simple que agregué a mi pregunta. Sin embargo, al leertarel código fuente nuevamente, me parece que debería leer la lista de archivos "sobre la marcha" si no se crea un archivo incremental. Desafortunadamente, tengo errores al compilartardesde la fuente ... :-(cpio, aparte degrep -v 'blocks$'. (head -n -1usa un búfer muy grande ...) Hace que esta solución sea un poco hack, pero no importa ;-)head -n -1solo usa 16 MB cuando se ejecuta con unos pocos GB de datos. Siempre puede usar perl: perl -ne 'print $ last; $ last = $ _'Un caso clásico de RTFM (¡todo!) . La
-Topción de GNUtarleerá los archivos que se archivarán desde otro archivo (en mi caso,/dev/stdintambién puede usar-), e incluso hay una--remove-filesopción:(usando la versión paralela de
xzpara la compresión, pero puede usar su compresor preferido en su lugar). Para ser utilizado como:EDITAR : Como señala Ole,
tarparece leer la lista completa de archivos con la-Topción por alguna razón. La siguiente prueba confirma esto:Hay un segundo retraso en mi sistema antes de que todos los archivos se impriman a la vez; en cambio, si el
tarcomando se reemplaza porcat, todos los archivos se imprimen a medida que se crean. He presentado una solicitud de soporte con la gente de alquitrán, veamos.EDITAR ^ 2 : El más reciente
tarde la fuente corrige esto. Todavía no está en Ubuntu 13.10, pero podría incluirse con 14.04.fuente
De alguna manera, esto no parece un buen trabajo para un compresor sólido (archivadores basados en cinta + compresión). Insertar archivos uno tras otro parece un trabajo
zipo algún otro formato que permita el acceso aleatorio a los archivos dentro del archivo y la inserción incremental.El hecho de que los archivos sean similares no ayudará mucho en ninguno de los casos. En
zip, los archivos se comprimen por separado, y en los compresores sólidos, generalmente hay una ventana dentro de la cual tiene lugar la compresión.Si los archivos están basados en texto, puede almacenar diferencias en comparación con un solo archivo de referencia. Para binario, es un poco más complicado pero se puede hacer.
También hay una forma formal (no solo de escritura, sino de sistemas de archivos adecuados). Por ejemplo, los sistemas de archivos ZFS y BTRFS ofrecen una compresión transparente. También puede usar este http://developer.berlios.de/projects/fusecompress
fuente
xzparece funcionar con un tamaño de diccionario predeterminado de 8M (en el nivel de compresión predeterminado-6), lo que parece ser suficiente para mi caso de uso. - Las diferencias en un archivo de referencia son buenas, pero primero se requiere construir un archivo de referencia. ¿Un sistema de archivos de compresión detectaría archivos con contenido casi idéntico?btrfstienen copia en escritura, por lo que si copia un archivo y modifica una parte del mismo, solo guarda las partes que ha cambiado. Si no está creando archivos de esta manera, supuestamente existen herramientas de deduplicación , pero aúnbtrfsno es un sistema de archivos maduro y estable y la deduplicación se encuentra en las primeras etapas de desarrollo. Pero ahora que lo pienso, ¿qué pasa con lessfs.com/wordpressPuede que no parezca obvio, pero apuesto a
squashfsque sería perfecto para esto, e incluso está implementado en el núcleo. Desde la versión 4.1squashfspuede manejar pseudo archivos como se especifica en lamksquashlínea de comando o mediante un script de shell ymksquashfsgenerará los archivos a medida que crea el archivo.Puede manejar tuberías , por ejemplo, puede capturar otro proceso
stdouten un archivo de squash montable, incluso quince , es bastante genial. En su caso, si se pudiera encontrar la logística de secuencia de comandos de la tubería de salida de su proceso a través de él, se puede envolver su proceso enteramente enmksquashfsy terminar con un único archivo. Aquí hay un poco dereadmecómo funciona y hay más aquí :fuente
testy un archivofileen este directorio. ¿Podría por favor dar un breve ejemplo?