J'ai 10k + fichiers totalisant plus de 20 Go que je dois concaténer en un seul fichier.
Y a-t-il un moyen plus rapide que
cat input_file* >> out
?
La manière préférée serait une commande bash, Python est également acceptable sinon considérablement plus lent.
bash
shell-script
files
cat
fsperrle
la source
la source
find
ne trie pas les fichiers de la même manière qu'un shell glob.out
se trouve sur un autre disque.Réponses:
Non, le chat est sûrement le meilleur moyen de le faire. Pourquoi utiliser python alors qu'il existe un programme déjà écrit en C à cet effet? Cependant, vous pouvez toutefois envisager d'utiliser
xargs
au cas où la longueur de la ligne de commande dépasseARG_MAX
et que vous en avez besoin de plusieurscat
. En utilisant des outils GNU, cela équivaut à ce que vous avez déjà:la source
find
est acheminéesort
. Sans cela, les fichiers seraient répertoriés dans un ordre arbitraire (défini par le système de fichiers, qui pourrait être un ordre de création de fichiers).bash
glob. Sinon, je ne vois aucun cas oùxargs
oucat
ne se comporterait pas comme prévu.xargs
appellera autantcat
que nécessaire pour éviter une erreur E2BIG de execve (2).L'allocation de l'espace pour le fichier de sortie en premier peut améliorer la vitesse globale car le système n'aura pas à mettre à jour l'allocation pour chaque écriture.
Par exemple, si sous Linux:
Un autre avantage est que s'il n'y a pas assez d'espace libre, la copie ne sera pas tentée.
Si cette option est activée
btrfs
, vous pouvez créercopy --reflink=always
le premier fichier (ce qui n'implique aucune copie de données et serait donc presque instantané) et ajouter le reste. S'il y a 10000 fichiers, cela ne fera probablement pas beaucoup de différence, sauf si le premier fichier est très volumineux.Il y a une API pour généraliser cela pour recopier tous les fichiers (les
BTRFS_IOC_CLONE_RANGE
ioctl
), mais je n'ai trouvé aucun utilitaire exposant cette API, vous devriez donc le faire en C (python
ou dans d'autres langues à condition qu'ils puissent appeler desioctl
s arbitraires ) .Si les fichiers source sont clairsemés ou ont de grandes séquences de caractères NUL, vous pouvez créer un fichier de sortie clairsemé (gain de temps et d'espace disque) avec (sur les systèmes GNU):
la source
>
ni>>
, mais1<>
comme je l'ai dit, écrire dans le fichier.<>
est l'opérateur de redirection de lecture / écriture Bourne / POSIX standard. Consultez le manuel de votre shell ou la spécification POSIX pour plus de détails. La valeur par défautfd
est0
pour l'<>
opérateur (<>
est court pour0<>
, comme<
est court pour0<
et>
court pour1>
), vous avez donc besoin de1
pour rediriger explicitement stdout. Ici, ce n'est pas tellement que nous avons besoin de read + write (O_RDWR
), mais que nous ne voulons pasO_TRUNC
(comme dans>
) qui désallouerait ce que nous venons d'allouer.dd
ou via la lecture.fallocate
les frais généraux seront annulésfind
, même si ce sera plus rapide la deuxième fois.btrfs
ouvre certainement des possibilités intéressantes.