Wie erstelle ich eine Datei vom Terminal aus, indem ich eine Reihe von Wörtern unendlich wiederhole?

19

Wie erstelle ich eine Datei vom Terminal aus, indem ich eine Reihe von Wörtern unendlich wiederhole? Ich brauche es, um eine riesige Datei für Analysezwecke wie 2-4 GB Größe zu erstellen. Gegenwärtig kopiere ich manuell das Einfügen von Zeilen in dieselbe Datei, um die Größe zu erhöhen.

Nisheet
quelle
1
Ich würde gerne eine Antwort sehen, die mit speziellen Unix-Dateien arbeitet, damit sie diesen Platz nicht wirklich einnehmen. Ist das möglich?
Délisson Junio
1
Du meinst etwas wirklich Unendliches wie mkfifo huge.tmp; while true; do yes "a dummy line" > huge.tmp; done?
Boldewyn

Antworten:

50

Es gibt eine einfache Möglichkeit, eine Zeile viele Male zu wiederholen:

yes we have no bananas | head -n 10000 > out.txt

Das Ergebnis ist out.txt mit 10.000 Zeilen, in denen "Wir haben keine Bananen" steht.


Um die Ausgabe auf eine genaue Anzahl von Bytes zu beschränken, verwenden Sie headdie -cOption 's' anstelle von -n. Dies erzeugt zum Beispiel genau 10 kB Text:

yes we have no bananas | head -c 10000 > out.txt
hobbs
quelle
2
OP will mit Bytes umgehen, nicht mit Zeilen.
Heemayl
4
Um ein Limit in Bytes anzugeben, verwenden Sie einfach head -c 1000010 kB anstelle von 10 head -n 10000k Zeilen.
Byte Commander
@ByteCommander ja, aber das verhindert nicht, dass die Ausgabe in der Mitte einer Zeile abgeschnitten wird. Da die Größe nicht genau sein muss, würde ich nur die Anzahl der Zeilen herausfinden, um die richtige Größe zu erhalten, und
aufrunden
1
Ich stimme zu, bin mir aber nicht sicher, ob das auch ein Problem wäre. Das OP hat nicht angegeben, welche Methode er will, aber Ihre Antwort enthält immer noch beide. Oh, und herzlichen Glückwunsch, dass Sie heute Ihren Ruf verdoppelt haben :)
Byte Commander
@ ByteCommander yep, fair.
Hobbs
10

Ich kann nicht empfehlen , Text unendlich zu wiederholen, aber Sie könnten mit Python eine ~ 2-GB-Datei mit wiederholtem Text wie folgt erstellen ...

python3 -c 'with open("bigfile", "w") as f: f.write(("hello world "*10+"\n")*2*10**7)'

Dadurch wird 10 Mal "Hallo Welt" gedruckt, eine neue Zeile erstellt und diese 20.000.000 Mal wiederholt, wobei das Ergebnis in die Datei geschrieben wird bigfile. Wenn alle Ihre Zeichen ASCII-Zeichen sind, entspricht jedes einem Byte. Berechnen Sie also entsprechend den Angaben, die Sie schreiben möchten.

Ihre CPU kann im Besitz sein. Mir geht der Arbeitsspeicher aus, wenn ich versuche, mehr als 10.000.000 Zeilen zu schreiben ...

Ich lasse zwar einen Toaster laufen

Zanna
quelle
OP will mit Bytes umgehen, nicht mit Zeilen.
Heemayl
@heemayl natürlich ist Ihre Antwort besser, aber ich habe (vage) erklärt, wie man berechnet, wie viele Zeilen verwendet werden müssen, um die gewünschten Bytes zu erhalten, damit ich meine Antwort nicht für völlig nutzlos halte
Zanna
4
@heemayl was macht dich so sicher, dass das OP bytes will? Die Frage besagt im Wesentlichen, dass das OP eine große Datei möchte. Die spezifische Größe ist sehr vage (2-4 GB), so dass ich wirklich bezweifle, dass es eine bestimmte Bytegrenze gibt.
Terdon
1
@heemayl ja, aber das ist sehr, sehr vage. Ich verstehe, dass das OP nur eine große Datei benötigt und sich nicht um die genaue Größe kümmert. Andernfalls hätten sie eine Größe anstelle eines so großen Größenbereichs angegeben.
Terdon
1
@cat ikr! <3python <3
Zanna
9

Perl hat den cleveren xOperator:

$ perl -e 'print "foo\n" x 5'
foo
foo
foo
foo
foo

Als einfache Lösung können Sie Ihre Zeile also ein paar Millionen Mal schreiben. Mit diesem Befehl wurde beispielsweise eine 3G-Datei erstellt:

perl -e 'print "This is my line\n" x 200000000' > file

Wenn Sie eine genaue Größe angeben müssen (in diesem Fall 2 GiB), können Sie Folgendes tun:

perl -e 'use bytes; while(length($str)<2<<20){ $str.="This is my line\n"} print "$str\n"' > file
terdon
quelle
Wenn Sie geduldig sind, können Sie Perl 6 Operatoren kühlen verwenden außer Perl 6 ist viel, viel, viel, viel langsamer: D
cat
@cat ist es wirklich? Ich habe 6 überhaupt nicht angerührt, aber ich hatte angenommen, dass es nur die perly Güte plus OO-Extras haben würde. Irgendeine Idee, warum es langsamer ist?
Terdon
1
Mein Kommentar war größtenteils glib, aber ich habe zu Beginn dieses Jahres festgestellt, dass Perl 6 ziemlich langsam ist, verglichen mit Python 3, das kanonisch viel langsamer ist als Perl 5 (das ich nicht getestet habe). Die Arbeit konzentriert sich auf Funktionen und Korrektheit, noch nicht auf Leistung, wurde jedoch als Ziel für 2015 aufgeführt. Ist Perl 6 für mich schnell genug? .
Katze
(Auf der anderen Seite, die Liste der Funktionen ist beeindruckend, um es gelinde auszudrücken.)
Katze
7
  • Fügen Sie die zu wiederholenden Wörter in eine Datei ein, z source.txt. Holen Sie sich die Größe der source.txt, in Bytes zB durch:

     stat -c '%s' source.txt
    
  • Legen Sie die Größe der Zieldatei fest, z. B. destination.txt2 GB oder 4 GB oder was auch immer. Konvertieren Sie die Größe in Bytes.

  • Teilen Sie die Größe der Zieldatei durch die Größe der Quelldatei. bashFließkomma-Arithmetik ist nicht möglich, wird aber in diesem Fall nicht benötigt.

  • Verwenden Sie ein forKonstrukt, um eine cat source.txtOperation die Divisionsergebniszeiten zu wiederholen . Dies entspricht in etwa der Größe der Zieldatei, die Sie durch Wiederholung erhalten können. Die Ausgabe der Operation wird in gespeichert destination.txt.

Angenommen, die Größe source.txtbeträgt 30 Byte, und wir möchten eine 2-GB-Datei erstellen, dann benötigen wir:

for ((i=0; i<=((16777216/30)); i++)); do cat source.txt; done >destination.txt

Hier setze ich die Obergrenze zum ((16777216/30))Zeitpunkt der Initialisierung; Sie können das Ergebnis auch hier abrufen.

Die Operation würde einige Zeit dauern; Je größer source.txt, desto weniger Zeit wird benötigt.

heemayl
quelle
1
Öffnet und schließt sich dies nicht destination.txteinmal für jede Iteration der Schleife?
Wiedereinsetzung von Monica - ζ--
@hexafraction Duh, behoben.
Heemayl
6

Sie können auch eine while-Schleife verwenden.

Beispiel: Inhalt von foo.txt(Dies ist Ihre Quelle):

foo
bar
foobar

bar.txtist leer (Dies ist Ihre Zieldatei). Sie können jetzt die folgende Schleife verwenden, um den Inhalt foo.txtmehrmals zu schreiben bar.txt:

while [ $(stat --format "%s" bar.txt) -lt 150 ] 
do 
    cat foo.txt >> bar.txt
done

Erläuterung:

  • stat --format "%s" bar.txtZeigt die Größe bar.txtin Bytes an.
  • while [ $(stat --format "%s" bar.txt) -lt 150 ] Die folgenden Aktionen werden wiederholt, bis die Zielgröße (in diesem Fall 150 Byte) erreicht ist.
  • cat foo.txt >> bar.txtfüge den Inhalt von foo.txtanbar.txt
Wayne_Yux
quelle
4

Feuer zuerst den Befehl:

dd if=/dev/urandom of=file.txt bs=2048 count=10

erstellt eine Datei auf einem Pfad der Größe bs * count zufällige Bytes, in unserem Fall 2048 * 10 = 20 KB. das kann je nach Anforderung geändert werden.

cat - > file.txt

Dieser Befehl leitet STDIN in eine Datei um. Sie müssen also zwei Zeilen eingeben und dann Strg + D drücken. Dann müssen Sie den folgenden Befehl ausführen:

for i in {1..n}; do cat file.txt file.txt > file2.txt && mv file2.txt file.txt; done

Wobei n eine ganze Zahl ist. Dadurch wird eine Datei mit 2 ^ (n + 1) Zeilen erstellt, indem die ursprünglichen zwei Zeilen dupliziert werden. So erstellen Sie eine Datei mit 16 Zeilen:

for i in {1..3}; do cat file.txt file.txt > file2.txt && mv file2.txt file.txt; done

Hier sind einige weitere Zahlen, die Ihnen den Einstieg erleichtern sollen:

n=15 will give you 65536 lines (if the original two lines were 'hello' and 'world' the file will be 384Kb)
n=20 will give you 2097152 lines (12Mb file with 'hello' and 'world' as the two starting lines)
n=25 will give you 67108864 lines (384Mb file with 'hello' and 'world' as the two starting lines)
Avani Badheka
quelle
2
OP will mit Bytes umgehen, nicht mit Zeilen.
Heemayl
OP ist auch weiterhin Kopierlinie zum Füllen der Datei. und mein erster Befehl hat bereits eine Datei gemäß den erforderlichen Speicherbytes erstellt.
Avani Badheka
@heemayl Das Newline-Zeichen belegt immer noch ein Byte, genau wie mein früherer Kommentar. Es ist ein legitimer Charakter. Das OP hat jedoch Worte spezifiziert , Avani, also glaube ich nicht, dass Ihre / dev / urandom-Technik ihre Frage beantwortet.
Mike S
Es hängt von / dev / urandom ab, ob Sie zufällige Bytes versuchen. Sogar Sie können einige Dateien, die so viele Datenbytes enthalten, selbst auswählen.
Avani Badheka
4

FIFOs sind wahrscheinlich das, wonach Sie suchen. Anstatt Ihr Programm mit einer bestimmten Datei aufzurufen, können Sie das Ergebnis eines Shell-Befehls über die Prozesssubstitution an das Programm binden, und das Programm sieht seine Ausgabe als Klartextdatei. Der Vorteil hierbei ist, dass Sie nicht mehr an Ihren Festplattenspeicher gebunden sind, sodass Sie Dateigrößen erreichen können, die andernfalls unmöglich wären, solange Ihr Programm nicht die gesamte Datei zuerst puffern und sie einfach zeilenweise analysieren muss. Verwenden Sie zum Beispiel die Antwort von @hobbs, um Inhalte zu generieren:

wc -c <(yes we have no bananas | head -n 5000000000)

Dies verleiht mir eine 95-Gigabyte-Datei (laut wc) ohne Kosten auf der Festplatte und kaum RAM, gerade genug, um das, was der Befehl zurückgibt, zu puffern, bevor es gelesen wird. Dies ist ungefähr so ​​nah an "unendlich", wie Sie bekommen werden.

Santo Guevarra
quelle