Le moyen le plus rapide de concaténer des files

J'ai 10k + files totalisant plus de 20 Go que j'ai besoin de concaténer dans un seul file.

Y a-t-il un moyen plus rapide que

cat input_file* >> out 

?

Le moyen préféré serait une command bash, Python est acceptable aussi si ce n'est pas considérablement plus lent.

Non, le chat est sûrement la meilleure façon de le faire. Pourquoi utiliser python quand il existe un programme déjà écrit en C à cette fin? Cependant, vous pouvez cependant envisager d'utiliser xargs si la longueur de la command line dépasse ARG_MAX et que vous avez besoin de plus d'un cat . En utilisant les outils GNU, cela équivaut à ce que vous avez déjà:

 find . -maxdepth 1 -type f -name 'input_file*' -print0 | sort -z | xargs -0 cat -- >>out 

Allouer d'abord l'espace pour le file de sortie peut améliorer la vitesse globale car le système n'aura pas à mettre à jour l'allocation pour chaque écriture.

Par exemple, si sur Linux:

 size=$({ find . -maxdepth 1 -type f -name 'input_file*' -printf '%s+'; echo 0;} | bc) fallocate -l "$size" out && find . -maxdepth 1 -type f -name 'input_file*' -print0 | sort -z | xargs -r0 cat 1<> out 

Un autre avantage est que s'il n'y a pas assez d'espace libre, la copy ne sera pas tentée.

Si sur btrfs , vous pouvez copy --reflink=always le premier file (ce qui n'implique aucune copy de données et sera donc presque instantané), et append le rest. S'il y a 10000 files, cela ne fera probablement pas beaucoup de différence, à less que le premier file ne soit très gros.

Il y a une API pour généraliser cela pour ref-copyr tous les files, mais je ne trouvais aucun utilitaire exposant cette API, donc il faudrait le faire en C (ou en python ou dans d'autres langues à condition de pouvoir appeler arbitraires ioctl s).

Si les files source sont rares ou contiennent de grandes séquences de caractères NUL, vous pouvez créer un file de sortie clairsemé (gain de time et d'espace disque) avec (sur les systèmes GNU):

 find . -maxdepth 1 -type f -name 'input_file*' -print0 | sort -z | xargs -r0 cat | cp --sparse=always /dev/stdin out