C'est exactement ce que cat
était fait pour. Puisqu'il s'agit de l'un des plus anciens outils GNU, je pense qu'il est très peu probable qu'un autre outil le fasse plus rapidement/mieux. Et ce n'est pas de la tuyauterie - il ne fait que rediriger la sortie.
Sous le capot
Il n'y a pas de moyen plus efficace que de copier le premier fichier, puis de copier le deuxième fichier après, et ainsi de suite. Les deux DOS copy
et cat
fais ça.
Chaque fichier est stocké indépendamment des autres fichiers sur le disque. Presque tous les systèmes de fichiers conçus pour stocker des données sur un périphérique de type disque fonctionnent par blocs. Voici une présentation très simplifiée de ce qui se passe :le disque est divisé en blocs de, disons 1ko, et pour chaque fichier le système d'exploitation stocke la liste des blocs qui le composent. La plupart des fichiers ne sont pas longs d'un nombre entier de blocs, de sorte que le dernier bloc n'est que partiellement occupé. En pratique, les systèmes de fichiers disposent de nombreuses optimisations, comme le partage du dernier bloc partiel entre plusieurs fichiers ou le stockage des « blocs 46798 à 47913 » plutôt que « bloc 46798, bloc 46799, … ». Lorsque le système d'exploitation doit créer un nouveau fichier, il recherche des blocs libres. Les blocs ne doivent pas nécessairement être consécutifs :si seuls les blocs 4, 5, 98 et 178 sont libres, vous pouvez toujours stocker un fichier de 4 ko. L'utilisation de blocs plutôt que de descendre au niveau de l'octet permet de trouver des blocs libres pour un fichier nouveau ou en croissance considérablement plus rapidement, et réduit les problèmes dus à la fragmentation lorsque vous créez ou agrandissez et supprimez ou réduisez un grand nombre de fichiers (laissant un nombre croissant de trous).
Vous pourriez prendre en charge des blocs partiels au milieu d'un fichier, mais cela ajouterait une complexité considérable, en particulier lors de l'accès aux fichiers de manière non séquentielle :pour sauter au 10340e octet, vous ne pourriez plus sauter au 100e octet du 11e bloc, vous auriez pour vérifier la longueur de chaque bloc intermédiaire.
Compte tenu de l'utilisation de blocs, vous ne pouvez pas simplement joindre deux fichiers, car en général, le premier fichier se termine au milieu du bloc. Bien sûr, vous pourriez avoir un cas particulier, mais uniquement si vous souhaitez supprimer les deux fichiers lors de la concaténation. Ce serait une manipulation très spécifique pour une opération rare. Une telle gestion spéciale ne vit pas d'elle-même, car sur un système de fichiers typique, de nombreux fichiers sont consultés en même temps. Donc, si vous souhaitez ajouter une optimisation, vous devez bien réfléchir :que se passe-t-il si un autre processus lit l'un des fichiers concernés ? Que se passe-t-il si quelqu'un essaie de concaténer A et B pendant que quelqu'un concatène A et C ? Etc. Dans l'ensemble, cette optimisation rare serait un énorme fardeau.
Dans l'ensemble, vous ne pouvez pas rendre la jonction de fichiers plus efficace sans faire de gros sacrifices ailleurs. Ça n'en vaut pas la peine.
Sur le fractionnement et la jonction
split
et cat
sont des moyens simples de fractionner et de joindre des fichiers. split
se charge de produire des fichiers nommés par ordre alphabétique, de sorte que cat *
fonctionne pour rejoindre.
Un inconvénient de cat
pour l'assemblage est qu'il n'est pas robuste contre les modes de défaillance courants. Si l'un des fichiers est tronqué ou manquant, cat
ne vous plaindrez pas, vous obtiendrez simplement une sortie endommagée.
Il existe des utilitaires de compression qui produisent des archives en plusieurs parties, tels que zipsplit
et rar -v
. Ils ne sont pas très unix, car ils compressent et compressent (assemblent plusieurs fichiers en un seul) en plus de les diviser (et inversement décompressent et décompressent en plus de se joindre). Mais ils sont utiles car ils vérifient que vous avez toutes les pièces et que les pièces sont complètes.
Il semble qu'il devrait y avoir un moyen plus efficace que de diriger tout le contenu via le
stdin
du système /stdout
Sauf que ce n'est pas vraiment ce qui se passe. Le shell connecte le stdout de cat
directement au fichier ouvert, ce qui signifie que "passer par stdout" revient à écrire sur le disque.