Wie fülle ich eine Datei auf die gewünschte Größe auf?

15

Ich habe eine Datei, die ich auffüllen möchte, bis sie 16 MB (16777216 Byte) erreicht. Derzeit sind es 16515072 Bytes. Die Differenz beträgt 262144 Bytes.

Wie fülle ich es auf?

Das scheint nicht zu funktionieren:

cp smallfile.img largerfile.img
dd if=/dev/zero of=largerfile.img bs=1 count=262144
Tarabyte
quelle
2
@Terabyte; Möchten Sie physisches oder logisches Auffüllen? Mit anderen Worten; Sollte die Datei nur eine Größe von 16777216 aufweisen (und möglicherweise Löcher enthalten) oder sollte sie auch diese Menge an Speicherplatz auf der Festplatte belegen? - BTW, eine Wahl bs=1in ddist in meiner Erfahrung sehr Runtime teuer.
Janis
5
truncate -s 16M thefile
Frostschutz
4
@frostschutz das wäre eine gute antwort, würdest du es als antwort posten.
Derobert
@derobert, Was ist mit StackExchange-Site-Benutzern, die legitime, einfache Antworten als Kommentare veröffentlichen?
user1717828
@ user1717828 nicht sicher, wahrscheinlich eine gute frage für meta.
Derobert

Antworten:

10

Löschen Sie das of=largerfile.txtund hängen Sie stdout an die Datei an:

dd if=/dev/zero bs=1 count=262144 >> largerfile.txt
Outurnate
quelle
1
seekist hier eine richtige Option.
0andriy
15

Neben den Antworten, um eine physische Auffüllung zu erhalten, können Sie auch den größten Teil der Auffüllfläche in der Datei leer lassen ("Löcher"), indem seekSie an die neue Endposition der Datei gehen und ein einzelnes Zeichen schreiben:

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

(Das hat den Vorteil, dass es viel leistungsfähiger ist bs=1und nicht viel zusätzlichen Speicherplatz belegt.)

Diese Methode scheint zu funktionieren, auch wenn Sie kein Zeichen hinzufügen, indem Sie if=/dev/nullund die endgültige gewünschte Dateigröße verwenden:

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

Eine performante Variante einer physikalischen Auffülllösung, die größere Blockgrößen verwendet, ist:

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
quelle
3
Richtig. In diesem Fall truncate -s +262144 largerfile.txtwäre auch schnell.
don_crissti
4

Die beste Antwort hier ist die von Janis (oben), da Sie die aktuelle Dateigröße vergessen und ohne Berechnung direkt auf die gewünschte Größe auffüllen können.

Es nutzt auch die Vorteile von Dateien mit geringer Dichte, die mit / dev / zero nicht erreicht werden.

Die Antwort könnte jedoch ordentlicher sein, da 'count' 0 sein darf und Sie trotzdem die Auffüllung erhalten:

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

(Bearbeiten: Dies ist korrekt für GNU dd, aber das Verhalten von count=0ist plattformspezifisch, siehe Kommentare.)

PeteC
quelle
Sie haben sich geirrt: count=0ist nicht angegeben, entspricht jedoch in der Regel der countAngabe, als kein Parameter angegeben wurde. Weitere Probleme: ddKürzt die Datei auf 16777216 Byte. Wenn Sie jedoch hoffen, dass am Ende eine Lücke entsteht, täuschen Sie sich, da Sie zuerst Daten nach der Lücke schreiben und später auf eine Größe kürzen müssten, die keine Daten enthält .
Schily
count = 0 entspricht in keiner Weise der Angabe eines Zählparameters. Wollen Sie damit sagen, dass dd if=/dev/zero of=somefilees dasselbe ist wie dd if=/dev/zero of=somefile count=0? Versuch es.
PeteC
Natürlich! count=0 ist dasselbe, als ob Sie überhaupt keinen Parameter count angegeben hätten. Dies gilt zumindest für alle Implementierungen, die aus den ursprünglichen Quellen abgeleitet wurden. Probieren Sie es aus, anscheinend haben Sie nie mit dem ursprünglichen ddBefehl gearbeitet.
Schily
Ich kann keine Dokumentation finden, in der 0 als eindeutiger Wert für die countBedeutung "Diesen Parameter ignorieren" angegeben ist. Kannst du welche finden? Ohne eine solche Dokumentation count=0bedeutet "Nullblöcke schreiben" und jede Abweichung davon ist ein Fehler ... (Originalquellen oder Nein).
PeteC
1
Dies war die POSIX-Dokumentation von vor Mai 2015, als der unterbestimmte Text korrigiert wurde.
Schily
1

Müssen Sie verwenden dd? Wenn Sie möchten, dass eine Datei eine bestimmte (logische) Länge hat, schreiben Sie einfach eine Null an die gewünschte Position. Die Bytes zwischen dem vorherigen Ende und dem geschriebenen Byte werden mit Null-Bytes angezeigt. Hier ist ein Beispiel mit 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

Warum die "- 2" in der Zeile? Das Skript schreibt ein Byte, also subtrahieren wir 1, um nach der Position vor diesem Byte zu suchen. Wir nehmen den anderen weg, weil die Suchposition nullindiziert ist.

BowlOfRed
quelle