Tengo más de 10k archivos por un total de más de 20GB que necesito concatenar en un solo archivo.
¿Hay una manera más rápida que
cat input_file* >> out
?
La forma preferida sería un comando bash, Python también es aceptable si no considerablemente más lento.
bash
shell-script
files
cat
fsperrle
fuente
fuente

findno clasifica los archivos de la misma manera que un shell glob.outse encuentra en otro disco.Respuestas:
No, el gato es seguramente la mejor manera de hacer esto. ¿Por qué usar python cuando ya hay un programa escrito en C para este propósito? Sin embargo, es posible que desee considerar el uso
xargsen caso de que la longitud de la línea de comando excedaARG_MAXy necesite más de unocat. Usando herramientas GNU, esto es equivalente a lo que ya tiene:fuente
findse canalizasort. Sin esto, los archivos se enumerarían en un orden arbitrario (definido por el sistema de archivos, que podría ser el orden de creación de archivos).bashglobo. De lo contrario, no veo ningún caso dondexargsocatno se comportaría como se esperaba.xargsllamará lo más que puedacatpara evitar un error E2BIG de execve (2).Asignar primero el espacio para el archivo de salida puede mejorar la velocidad general ya que el sistema no tendrá que actualizar la asignación para cada escritura.
Por ejemplo, si en Linux:
Otro beneficio es que si no hay suficiente espacio libre, la copia no se intentará.
Si está activado
btrfs, podríacopy --reflink=alwaysel primer archivo (lo que implica que no hay copia de datos y, por lo tanto, sería casi instantáneo), y agregar el resto. Si hay 10000 archivos, eso probablemente no hará mucha diferencia, a menos que el primer archivo sea muy grande.Hay una API para generalizar eso para volver a copiar todos los archivos (the
BTRFS_IOC_CLONE_RANGEioctl), pero no pude encontrar ninguna utilidad que exponga esa API, por lo que tendrías que hacerlo en C (pythonu otros lenguajes siempre que puedan llamarioctls arbitrarios ) .Si los archivos de origen son escasos o tienen secuencias grandes de caracteres NUL, puede crear un archivo de salida disperso (ahorrando tiempo y espacio en disco) con (en sistemas GNU):
fuente
>ni>>, pero1<>como dije escribir en el archivo.<>es el operador estándar de redirección de lectura + escritura Bourne / POSIX. Consulte su manual de shell o la especificación POSIX para más detalles. El valor predeterminadofdes0para el<>operador (<>es corto para0<>, como<es corto para0<y>corto para1>), por lo que necesita1redireccionar explícitamente stdout. Aquí, no es tanto que necesitemos leer + escribir (O_RDWR), sino que no queremosO_TRUNC(como en>) lo que desasignaría lo que acabamos de asignar.ddo mediante la lectura.fallocateque negará la sobrecarga del extrafind, aunque será más rápido la segunda vez.btrfsSin embargo, sin duda abre algunas posibilidades interesantes.