Comment remplir un fichier à la taille souhaitée?

15

J'ai un fichier que je veux remplir jusqu'à ce qu'il atteigne 16 Mo (16777216 octets). Actuellement, il est de 16515072 octets. La différence est de 262144 octets.

Comment le rembourrer?

Cela ne semble pas fonctionner:

cp smallfile.img largerfile.img
dd if=/dev/zero of=largerfile.img bs=1 count=262144
tarabyte
la source
2
@terabyte; voulez-vous un remplissage physique ou un remplissage logique? En d'autres termes; le fichier doit-il uniquement afficher une taille de 16777216 (et peut contenir des trous) ou doit-il également occuper cette quantité de stockage sur le disque? - BTW, choisir un bs=1in ddest, selon mon expérience, un temps d'exécution très coûteux.
Janis
5
truncate -s 16M thefile
frostschutz
4
@frostschutz ce serait une bonne réponse, si vous deviez l'afficher comme réponse.
derobert
@derobert, Qu'en est-il des utilisateurs du site StackExchange qui publient des réponses légitimes et simples sous forme de commentaires?
user1717828
@ user1717828 pas sûr, probablement une bonne question pour la méta.
derobert

Réponses:

10

Déposez of=largerfile.txtet ajoutez stdout au fichier:

dd if=/dev/zero bs=1 count=262144 >> largerfile.txt
Outurnate
la source
1
seekest une bonne option ici.
0andriy
15

Outre les réponses pour obtenir un remplissage physique, vous pouvez également laisser la plupart de l'espace de remplissage dans le fichier juste vide ("trous"), en seekentrant dans la nouvelle position finale du fichier et en écrivant un seul caractère:

dd if=/dev/zero of=largerfile.txt bs=1 count=1 seek=16777215

(qui a l'avantage d'être beaucoup plus performant, notamment avec bs=1, et n'occupe pas de grandes quantités d'espace disque supplémentaire).

Cette méthode semble fonctionner même sans ajouter de caractère, en utilisant if=/dev/nullet la taille de fichier finale souhaitée:

dd if=/dev/null of=largerfile.txt bs=1 count=1 seek=16777216

Une variante performante d'une solution de remplissage physique qui utilise des blocs de plus grandes tailles est:

padding=262144 bs=32768 nblocks=$((padding/bs)) rest=$((padding%bs))
{
  dd if=/dev/zero bs=$bs count=$nblocks
  dd if=/dev/zero bs=$rest count=1
} 2>/dev/null >>largerfile.txt
Janis
la source
3
Correct. Dans ce cas, truncate -s +262144 largerfile.txtserait également rapide.
don_crissti
4

La meilleure réponse ici est celle de Janis (ci-dessus) car elle vous permet d'oublier la taille du fichier actuel et de passer directement à la taille souhaitée sans aucun calcul.

Il tire également parti des fichiers clairsemés, ce qui n'est pas le cas avec l'ajout de / dev / zero.

La réponse pourrait être plus nette, car `` count '' peut être égal à 0 et vous obtenez toujours le remplissage:

dd if=/dev/null of=largerfile.txt bs=1 count=0 seek=16777216

(Edit: c'est correct pour GNU dd, mais le comportement de count=0est spécifique à la plateforme, voir les commentaires)

PeteC
la source
Vous vous trompez: count=0n'est pas spécifié, mais est généralement le même que lorsqu'aucun countparamètre n'a été spécifié. Plus de problèmes: ddtronque le fichier à 16777216 octets, mais si vous espérez que cela crée un trou à la fin, vous vous trompez car vous devrez d'abord écrire des données après le trou et ensuite le tronquer à une taille qui ne contient aucune donnée .
schily
count = 0 n'a rien à voir avec la spécification d'aucun paramètre de comptage. Voulez-vous dire que dd if=/dev/zero of=somefilec'est la même chose que dd if=/dev/zero of=somefile count=0? Essayez-le.
PeteC
Bien sûr! count=0 est la même que si vous n'aviez pas du tout spécifié de paramètre de comptage. Cela est vrai au moins pour toutes les implémentations dérivées des sources d'origine. Essayez-le, il semble que vous n'ayez jamais travaillé avec la ddcommande d' origine .
schily
Je ne trouve aucune documentation spécifiant 0 comme valeur unique pour countsignifier «ignorer ce paramètre». Pouvez-vous en trouver? Sans une telle documentation, count=0signifie «écrire zéro bloc» et tout écart par rapport à cela est un bug ... (sources originales ou non).
PeteC
1
Il s'agissait de la documentation POSIX d'avant mai 2015 lorsque le texte sous-spécifié a été corrigé.
schily
1

Devez-vous utiliser dd? Si vous voulez qu'un fichier ait une longueur (logique) particulière, écrivez simplement un zéro à la position souhaitée. Les octets entre la fin précédente et l'octet écrit seront affichés comme ayant des octets nuls. Voici un exemple d'utilisation de perl.

$ echo Hello > file
$ ls -l file
-rw-r--r-- 1 user group 6 Apr 16 22:59 file
$ perl -le 'open(my $f,"+<","file"); seek($f, 16777216 - 2, 0); print $f "\0"'
$ ls -ln file
-rw-r--r-- 1 user group 16777216 Apr 16 22:59 file

Pourquoi le "- 2" dans la ligne? Le script écrit un octet, nous soustrayons donc 1 pour rechercher la position avant cet octet. Nous enlevons l'autre parce que la position de recherche est indexée sur zéro.

BowlOfRed
la source