Come creare un file dal terminale ripetendo una serie di parole all'infinito?


19

Come creare un file dal terminale ripetendo una serie di parole all'infinito? Ne ho bisogno per creare un file enorme per scopi di analisi come 2-4 GB di dimensioni. Attualmente sto copiando manualmente le linee di incollaggio nello stesso file per aumentare le dimensioni.


1
Mi piacerebbe vedere una risposta che lavora con file unix speciali, quindi non occuperebbe davvero quello spazio. È possibile?
Délisson Junio,

1
Intendi qualcosa di veramente infinito mkfifo huge.tmp; while true; do yes "a dummy line" > huge.tmp; done?
Boldewyn,

Risposte:


50

C'è un modo semplice per ripetere una riga molte volte:

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

risulterà in out.txt contenente 10.000 righe che dicono "non abbiamo banane".


Per limitare l 'output a un numero esatto di byte, utilizzare l head' -copzione anziché -n. Ad esempio, questo genera esattamente 10 kB di testo:

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

2
OP vuole occuparsi dei byte, non delle linee.
heemayl,

4
Per specificare un limite in byte, utilizzare semplicemente head -c 10000per 10 kB anziché head -n 10000per 10k righe.
Byte Commander

@ByteCommander sì, ma ciò non impedisce che l'output venga interrotto nel mezzo di una riga. Dal momento che la dimensione non deve essere precisa, vorrei solo capire il numero di righe per ottenere la giusta dimensione e arrotondare per
eccesso

1
Sono d'accordo, ma non sono sicuro che sarebbe un problema. L'OP non ha specificato quale metodo desidera, ma la tua risposta contiene ancora entrambi. Oh, e congratulazioni per aver raddoppiato il tuo punteggio di reputazione oggi :)
Byte Comandante

@ByteCommander sì, giusto.
Hobbs,

10

Non posso raccomandare di ripetere all'infinito il testo, ma potresti creare un file ~ 2GB di testo ripetuto con Python in questo modo ...

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

Che stamperà "ciao mondo" 10 volte e farà una nuova riga, e lo ripeterà 20.000.000 di volte, scrivendo il risultato nel file bigfile. Se tutti i tuoi caratteri sono ASCII, ognuno è un byte, quindi calcola in modo appropriato a seconda di ciò che vuoi scrivere ...

La tua cpu potrebbe essere di proprietà. A corto di RAM se provo a fare più di 10.000.000 di righe ...

Sto facendo funzionare un tostapane


OP vuole occuparsi dei byte, non delle linee.
heemayl,

@heemayl ovviamente la tua risposta è migliore, ma ho (vagamente) spiegato come calcolare quante linee usare per ottenere i byte desiderati, quindi non credo che la mia risposta sia assolutamente inutile
Zanna,

4
@heemayl cosa ti rende così sicuro che l'OP vuole byte? La domanda afferma essenzialmente che l'OP vuole un file di grandi dimensioni. La dimensione specifica è molto vaga (2-4 GB), quindi dubito davvero che ci sia un limite di byte specifico in mente.
terdon,

1
@heemayl sì, ma è molto, molto vago. La mia comprensione è che l'OP vuole solo un file di grandi dimensioni e non si preoccupa di una dimensione esatta. Altrimenti, avrebbero dato una taglia invece di una così vasta gamma di dimensioni.
terdon,

1
@cat ikr! <3python <3
Zanna,

9

Perl ha l' xoperatore elegante :

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

Quindi, come soluzione semplice, potresti semplicemente scrivere la riga qualche milione di volte. Ad esempio, questo comando ha creato un file 3G:

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

Se devi specificare una dimensione esatta (2 GiB in questo caso), puoi fare:

perl -e 'use bytes; while(length($str)<2<<20){ $str.="This is my line\n"} print "$str\n"' > file

Se sei paziente, puoi usare gli operatori Perl 6 fantastici, tranne che Perl 6 è molto, molto, molto più lento: D
cat

@cat è davvero? Non ho ancora toccato 6, ma avevo pensato che avrebbe avuto tutta la perfezione bontà più extra OO. Qualche idea sul perché sia ​​più lento?
terdon,

1
Il mio commento è stato per lo più loquace, ma ho scoperto all'inizio di quest'anno che Perl 6 è piuttosto lento, rispetto a Python 3 che è canonicamente molto più lento di Perl 5 (che non ho testato). Il lavoro si concentra su funzionalità e correttezza, non ancora sulle prestazioni, ma è stato elencato come obiettivo per il 2015. Inoltre, Perl 6 è abbastanza veloce per me? .
gatto,

(D'altra parte, l'elenco delle funzionalità è a dir poco impressionante .)
cat

7
  • Inserisci l'insieme di parole da ripetere in un file ad es source.txt. Ottieni la dimensione del source.txt, in byte, ad esempio:

     stat -c '%s' source.txt
    
  • Decidi la dimensione del file di destinazione destination.txt, ad esempio 2 GB o 4 GB o altro. Converti la dimensione in byte.

  • Dividi la dimensione del file di destinazione per la dimensione del file di origine. bashnon può eseguire l'aritmetica in virgola mobile, ma in questo caso non è necessaria.

  • Utilizzare un forcostrutto per ripetere cat source.txtun'operazione il risultato della divisione volte. Questo sarebbe approssimativo più vicino alla dimensione del file di destinazione che è possibile ottenere ripetendo. L'output dell'operazione viene salvato in destination.txt.

Ad esempio, supponendo che source.txtsia di 30 byte e vogliamo creare un file da 2 GB, abbiamo bisogno di:

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

Qui sto impostando il limite superiore entro ((16777216/30))al momento dell'inizializzazione; puoi ottenere il risultato e metterlo anche qui.

L'operazione richiederebbe del tempo; più grande è source.txt, meno tempo sarà necessario.


1
Questo non si apre e si chiude destination.txtuna volta per ogni iterazione del ciclo?
Ripristina Monica - ζ--

@hexafraction Duh, risolto.
heemayl,

6

Puoi anche usare un while-loop.

Esempio: contenuto di foo.txt(Questa è la tua fonte):

foo
bar
foobar

bar.txtè vuoto (questo è il tuo file di destinazione). È ora possibile eseguire il ciclo seguente per scrivere il contenuto foo.txtpiù volte in bar.txt:

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

Spiegazione:

  • stat --format "%s" bar.txtvisualizza la dimensione bar.txtin byte.
  • while [ $(stat --format "%s" bar.txt) -lt 150 ] le seguenti azioni verranno ripetute fino al raggiungimento della dimensione target (in questo caso 150 byte).
  • cat foo.txt >> bar.txtaggiungere il contenuto di foo.txtabar.txt

4

prima di tutto il comando:

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

creerà un file sul percorso di dimensione bs * conta byte casuali, nel nostro caso 2048 * 10 = 20Kb. che può essere modificato secondo il requisito.

cat - > file.txt

Questo comando reindirizza STDIN su un file, quindi dovrai inserire due righe e quindi premere Ctrl + D. Quindi dovrai eseguire il comando seguente:

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

Dove n è un numero intero. Questo creerà un file con 2 ^ (n + 1) righe, duplicando le due righe originali. Quindi per creare un file con 16 righe devi fare:

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

Ecco alcuni altri numeri per iniziare:

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)

2
OP vuole occuparsi dei byte, non delle linee.
heemayl,

OP è anche mantenere la linea di coping per il riempimento del file. e il mio primo comando ha già creato il file secondo i byte di memoria richiesti.
Avani badheka,

@heemayl il carattere di nuova riga occupa ancora un byte, come nel mio commento precedente. È un personaggio legittimo. Tuttavia, l'OP ha specificato le parole , Avani, quindi non credo che la tua tecnica / dev / urandom risponda alla loro domanda.
Mike S,

Dipende da / dev / urandom, se si stanno provando dei byte casuali. Anche tu puoi scegliere i tuoi file che contengono così tanti byte di dati.
Avani badheka,

4

I FIFO sono probabilmente quello che stai cercando. Invece di chiamare il tuo programma con un determinato file, puoi legare il risultato di un comando shell ad esso tramite la sottotitolazione del processo e il programma vedrà il suo output come un file di testo semplice. Il vantaggio qui è che non sei più limitato dal tuo spazio su disco, quindi puoi raggiungere dimensioni di file altrimenti impossibili, a condizione che il tuo programma non debba prima bufferizzare l'intero file e semplicemente analizzarlo riga per riga. Ad esempio, usando la risposta di @hobbs per generare contenuto:

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

Questo mi dà un file di 95 gigabyte (secondo wc) senza alcun costo nello spazio dell'HDD e quasi nessuna RAM, quanto basta per bufferizzare ciò che il comando restituisce prima che venga letto. Questo è quasi "infinitamente" quanto si arriva.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.