Si j'ai un gros fichier et que je dois le diviser en morceaux de 100 mégaoctets, je le ferai
split -b 100m myImage.iso
Cela me donne généralement quelque chose comme
xaa
xab
xac
xad
Et pour les rassembler, j'utilise
cat x* > myImage.iso
Il semble qu'il devrait y avoir un moyen plus efficace que de lire chaque ligne de code d'un groupe de fichiers avec cat
et de rediriger la sortie vers un nouveau fichier. Comme une façon d'ouvrir simplement deux fichiers, de supprimer le marqueur EOF
du premier et de les connecter - sans avoir à parcourir tout le contenu.
Windows/DOS a une commande de copie pour les fichiers binaires. L'aide mentionne que cette commande a été conçue pour pouvoir combiner plusieurs fichiers. Il fonctionne avec cette syntaxe: (/b
est pour le mode binaire)
copy /b file1 + file2 + file3 outputfile
Existe-t-il quelque chose de similaire ou une meilleure façon de joindre de gros fichiers sur Linux que cat?
Mise à jour
Il semble que cat
soit en fait la bonne et la meilleure façon de joindre des fichiers. Heureux de savoir que j'utilisais la bonne commande depuis le début :) Merci à tous pour vos commentaires.
C'est exactement pour cela que cat
a été conçu. Comme 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 la tuyauterie - c'est seulement rediriger la sortie.
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. DOS copy
et cat
le font.
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 1 Ko, et pour chaque fichier, le système d'exploitation stocke la liste des blocs qui le composent. La plupart des fichiers ne sont pas un nombre entier de blocs de long, donc le dernier bloc n'est que partiellement occupé. En pratique, les systèmes de fichiers ont 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 ê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 d'accélérer considérablement la recherche de blocs libres pour un fichier nouveau ou en croissance, 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 des trous).
Vous pouvez prendre en charge des blocs partiels en milieu de fichier, mais cela ajouterait une complexité considérable, en particulier lors de l'accès non séquentiel à des fichiers: pour passer 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.
Étant donné 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 spécial, 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 accessibles en même temps. Donc, si vous souhaitez ajouter une optimisation, vous devez réfléchir attentivement: que se passe-t-il si un autre processus lit l'un des fichiers impliqué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 ne vaut pas le coup.
split
et cat
sont des moyens simples de fractionner et de joindre des fichiers. split
s'occupe de produire des fichiers nommés par ordre alphabétique, afin que cat *
fonctionne pour rejoindre.
Un inconvénient de cat
pour la jonction 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 se plaindra pas, vous obtiendrez simplement une sortie endommagée.
Il existe des utilitaires de compression qui produisent des archives en plusieurs parties, telles que zipsplit
et rar -v
. Ils ne sont pas très unixy, car ils compressent et emballent (assemblent plusieurs fichiers en un seul) en plus de fractionner (et inversement décompresser et décompresser 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 canaliser tout le contenu via le
stdin
/stdout
du système
Sauf que ce n'est pas vraiment ce qui se passe. Le shell connecte la sortie standard de cat
directement au fichier ouvert, ce qui signifie que "passer par la sortie standard" équivaut à écrire sur le disque.
J'ai eu une fois exactement ce problème: je voulais joindre certains fichiers, mais je n'avais pas assez d'espace disque pour les contenir deux fois.
J'ai donc écrit un tas de programmes:
Cela m'a permis de faire quelque chose comme
partto sourcefile | mybuffer 128M >>cumufile
et supprimant ainsi le fichier source alors que 128M était encore non écrit. Un peu dangereux, mais si les données ne sont pas si précieuses, ou qu'elles existent ailleurs, c'est faisable.
Si nécessaire, je peux fournir la source.
division des fichiers
Fractionner par taille
Si vous voulez diviser un gros fichier en petits fichiers et choisir le nom et la taille des petits fichiers de sortie, c'est la voie.
split -b 500M videos\BigVideoFile.avi SmallFile.
De cette façon, vous choisissez de diviser un gros fichier en parties plus petites de 500 Mo. Vous souhaitez également que les noms des fichiers de pièce soient SmallFile. Notez que vous avez besoin d'un point après le nom du fichier. Le résultat devrait être la génération de nouveaux fichiers comme celui-ci:
SmallFile.ab SmallFile.ad SmallFile.af SmallFile.ah SmallFile.aj
SmallFile.aa SmallFile.ac SmallFile.ae SmallFile.ag SmallFile.ai SmallFile.ak
...
Fractionné par nombre de lignes
De cette façon, vous diviserez le fichier texte en fichiers plus petits limités à 50 lignes.
split -l 50 text_to_split.txt
Le résultat devrait être quelque chose comme ceci:
xaa xab xac ...
Fractionner par octets
Fractionner en petits fichiers avec une taille personnalisée de petits fichiers en octets:
split -b 2048 BigFile.mp4
Le résultat doit être similaire au résultat de Fractionnement par nombre de lignes .
jonction de fichiers
Vous pouvez joindre des fichiers de deux manières. Le premier est:
cat SmallFile.* > OutputBigVideoFile.avi
ou avec:
cat SmallFile.?? > OutputBigVideoFile.avi
Remarque: Lorsque vous joignez des fichiers, les petits fichiers ne doivent pas être endommagés. Tous les petits fichiers (partiels) doivent également se trouver dans le même répertoire.
Techniquement parlant, c'est un moyen d'accéder à l'intégralité du fichier sans avoir à lire et à écrire l'intégralité du contenu, et pourrait être utile pour les fichiers volumineux ou s'il reste peu d'espace:
$ mkfifo myImage.iso
$ cat xa{a..g} > myImage.iso &
Et puis utilisez myImage.iso
, par exemple
$ md5sum myImage.iso
Bien sûr, myImage.iso
est un fichier spécial (nommé pipe) et non un fichier normal, donc cela peut être utile ou non selon ce que vous essayez de faire.