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
find
no clasifica los archivos de la misma manera que un shell glob.out
se 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
xargs
en caso de que la longitud de la línea de comando excedaARG_MAX
y necesite más de unocat
. Usando herramientas GNU, esto es equivalente a lo que ya tiene:fuente
find
se 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).bash
globo. De lo contrario, no veo ningún caso dondexargs
ocat
no se comportaría como se esperaba.xargs
llamará lo más que puedacat
para 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=always
el 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_RANGE
ioctl
), pero no pude encontrar ninguna utilidad que exponga esa API, por lo que tendrías que hacerlo en C (python
u otros lenguajes siempre que puedan llamarioctl
s 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 predeterminadofd
es0
para el<>
operador (<>
es corto para0<>
, como<
es corto para0<
y>
corto para1>
), por lo que necesita1
redireccionar 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.dd
o mediante la lectura.fallocate
que negará la sobrecarga del extrafind
, aunque será más rápido la segunda vez.btrfs
Sin embargo, sin duda abre algunas posibilidades interesantes.