Jak utworzyć plik z terminala, powtarzając nieskończenie zestaw słów?

19

Jak utworzyć plik z terminala, powtarzając nieskończenie zestaw słów? Potrzebuję go, aby utworzyć ogromny plik do analizowania, taki jak rozmiar 2-4 GB. Obecnie ręcznie kopiuję wklejanie linii do tego samego pliku, aby zwiększyć rozmiar.

Nisheet
źródło
1
Chciałbym zobaczyć odpowiedź działającą ze specjalnymi plikami uniksowymi, więc tak naprawdę nie zajmowałaby tego miejsca. Czy to jest możliwe?
Délisson Junio
1
Masz na myśli coś naprawdę nieskończonego mkfifo huge.tmp; while true; do yes "a dummy line" > huge.tmp; done?
Boldewyn

Odpowiedzi:

50

Jest prosty sposób, aby powtórzyć wiersz wiele razy:

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

spowoduje, że plik out.txt zawiera 10 000 wierszy, z których wszystkie mówią „nie mamy bananów”.


Aby ograniczyć wyjście do dokładnej liczby bajtów, użycia headjest -copcją zamiast -n. Na przykład generuje dokładnie 10 kB tekstu:

yes we have no bananas | head -c 10000 > out.txt
Hobbs
źródło
2
OP chce zajmować się bajtami, a nie liniami.
heemayl
4
Aby określić limit bajtów, po prostu użyj head -c 10000dla 10 kB zamiast head -n 10000dla 10 k linii.
Bajt Dowódca
@ByteCommander tak, ale nie zapobiegnie to odcięciu wyjścia w środku linii. Ponieważ rozmiar nie musi być dokładny, po prostu ustalę liczbę linii, aby uzyskać odpowiedni rozmiar, i zaokrąglę w górę :)
hobbs
1
Zgadzam się, ale nie jestem pewien, czy to też byłby problem. OP nie określił, której metody chce, ale twoja odpowiedź wciąż zawiera oba. Aha, i gratulacje za podwojenie dziś wyniku reputacji :)
Byte Commander
@ByteCommander tak, uczciwie.
hobbs
10

Nie mogę polecić nieskończonego powtarzania tekstu, ale możesz utworzyć plik o wielkości ~ 2 GB z powtarzającym się tekstem z pythonem tak ...

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

Spowoduje to wydrukowanie „hello world” 10 razy i utworzenie nowego wiersza, i powtórzenie tego 20 000 000 razy, zapisując wynik w pliku bigfile. Jeśli wszystkie znaki są ASCII, to każdy ma jeden bajt, więc odpowiednio obliczyć w zależności od tego, co chcesz napisać ...

Twoja jednostka centralna może być własnością. Skończy mi się pamięć RAM, jeśli spróbuję wykonać więcej niż 10 000 000 linii ...

Ale uruchamiam toster

Zanna
źródło
OP chce zajmować się bajtami, a nie liniami.
heemayl
@ heemayl oczywiście twoja odpowiedź jest lepsza, ale ja (niejasno) wyjaśniłem, jak obliczyć, ile wierszy użyć, aby uzyskać pożądane bajty, więc nie sądzę, że moja odpowiedź jest całkowicie bezużyteczna
Zanna
4
@ heemayl, co sprawia, że ​​jesteś tak pewien, że OP chce bajtów? Pytanie zasadniczo mówi, że OP chce dużego pliku. Konkretny rozmiar jest bardzo niejasny (2-4 GB), więc naprawdę wątpię, aby istniał określony limit bajtów.
terdon
1
@ heemayl tak, ale to bardzo, bardzo niejasne. Rozumiem, że OP chce tylko dużego pliku i nie dba o dokładny rozmiar. W przeciwnym razie podali rozmiar zamiast tak ogromnego zakresu rozmiarów.
terdon
1
@cat ikr! <3python <3
Zanna
9

Perl ma fajny xoperator:

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

Tak więc, jako proste rozwiązanie, możesz napisać swoją linię kilka milionów razy. Na przykład to polecenie utworzyło plik 3G:

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

Jeśli musisz podać dokładny rozmiar (w tym przypadku 2 GiB), możesz:

perl -e 'use bytes; while(length($str)<2<<20){ $str.="This is my line\n"} print "$str\n"' > file
terdon
źródło
Jeśli jesteś cierpliwy, możesz używać fajnych operatorów Perla 6, z wyjątkiem tego, że Perl 6 jest znacznie, dużo, dużo, dużo wolniejszy: D
cat
@cat to naprawdę? W ogóle nie dotknąłem 6, ale założyłem, że będzie miał po prostu całą dobroć plus dodatki OO. Wiesz, dlaczego jest wolniejszy?
terdon
1
Mój komentarz był głównie wygadany, ale znalazł się na początku tego roku, że Perl 6 jest dość powolny w porównaniu do Python 3, który jest znacznie wolniejszy niż kanonicznie Perl 5 (który nie testowałem). Praca koncentruje się na funkcjach i poprawności, jeszcze nie na wydajności, ale została wymieniona jako cel na 2015 rok. Czy Perl 6 jest dla mnie wystarczająco szybki? .
kot
(Z drugiej strony lista funkcji jest co najmniej imponująca .)
cat
7
  • Umieść zestaw słów do powtórzenia w pliku np source.txt. Uzyskaj rozmiar source.txtbajtów, np. Przez:

     stat -c '%s' source.txt
    
  • Wybierz rozmiar pliku docelowego, np. destination.txt2 GB lub 4 GB lub cokolwiek innego. Konwertuj rozmiar w bajtach.

  • Podziel rozmiar pliku docelowego przez rozmiar pliku źródłowego. bashnie może wykonywać arytmetyki zmiennoprzecinkowej, ale w tym przypadku nie jest to konieczne.

  • Użyj forkonstruktu, aby powtórzyć cat source.txtoperację razy wynik podziału. Byłby to najbliższy rozmiar docelowego pliku, jaki można uzyskać przez powtórzenie. Dane wyjściowe operacji są zapisywane w destination.txt.

Na przykład, zakładając, że source.txtma on 30 bajtów i chcemy utworzyć plik o wielkości 2 GB, potrzebujemy:

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

Tutaj ustawiam górny limit ((16777216/30))przy czasie inicjalizacji; możesz uzyskać wynik i umieścić go tutaj.

Operacja zajmie trochę czasu; im większy source.txt, tym mniej czasu będzie potrzebne.

heemayl
źródło
1
Czy to nie otwiera się i zamyka destination.txtraz dla każdej iteracji pętli?
Przywróć Monikę - ζ--
@hexafraction Duh, naprawiono.
heemayl
6

Możesz także użyć whilepętli.

Przykład: Treść foo.txt(To jest twoje źródło):

foo
bar
foobar

bar.txtjest pusty (to jest twój plik docelowy). Możesz teraz wykonać następującą pętlę, aby zapisać zawartość foo.txtwielokrotnie w bar.txt:

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

Wyjaśnienie:

  • stat --format "%s" bar.txtwyświetla rozmiar bar.txtw bajtach.
  • while [ $(stat --format "%s" bar.txt) -lt 150 ] następujące działania będą powtarzane, aż do osiągnięcia rozmiaru docelowego (w tym przypadku 150 bajtów).
  • cat foo.txt >> bar.txtdołącz zawartość foo.txtdobar.txt
Wayne_Yux
źródło
4

Najpierw wystrzel komendę:

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

utworzy plik na ścieżce o rozmiarze bs * zlicza losowe bajty, w naszym przypadku 2048 * 10 = 20 KB. które można zmienić zgodnie z wymaganiami.

cat - > file.txt

To polecenie przekierowuje STDIN do pliku, więc musisz wprowadzić dwa wiersze, a następnie nacisnąć Ctrl + D. Następnie musisz uruchomić następujące polecenie:

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

Gdzie n jest liczbą całkowitą. Spowoduje to utworzenie pliku zawierającego 2 ^ (n + 1) linii, poprzez skopiowanie oryginalnych dwóch linii. Aby utworzyć plik z 16 liniami, wykonaj:

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

Oto kilka liczb na początek:

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
źródło
2
OP chce zajmować się bajtami, a nie liniami.
heemayl
OP kontynuuje również kopiowanie linii do wypełnienia pliku. a moje pierwsze polecenie już utworzyło plik zgodnie z wymaganymi bajtami pamięci.
Avani badheka
@ heemayl znak nowej linii nadal zajmuje bajt, tak jak mój poprzedni komentarz. To legalna postać. Jednak OP określił słowa Avani, więc nie sądzę, aby twoja technika / dev / urandom odpowiadała na ich pytania.
Mike S
Zależy od / dev / urandom, czy próbujesz losowych bajtów. Nawet ty możesz wybrać własne pliki, które zawierają tyle bajtów danych.
Avani badheka
4

FIFO są prawdopodobnie tym, czego szukasz. Zamiast wywoływać program z danym plikiem, możesz powiązać z nim wynik polecenia powłoki poprzez podstawienie procesu, a program zobaczy wynik w postaci pliku jawnego tekstu. Zaletą jest to, że nie jesteś już ograniczony miejscem na dysku, dzięki czemu możesz osiągnąć rozmiary plików, które w przeciwnym razie byłyby niemożliwe, o ile twój program nie musi najpierw buforować całego pliku i może po prostu parsować go wiersz po wierszu. Na przykład użycie odpowiedzi @hobbs do wygenerowania treści:

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

To pożycza mi plik 95 gigabajtów (według wc) bez żadnych kosztów w przestrzeni na dysku twardym i prawie żadnej pamięci RAM, tylko tyle, aby buforować to, co komenda zwraca, zanim zostanie odczytana. Jest to tak blisko „nieskończoności”, jak tylko się da.

Santo Guevarra
źródło