Bagaimana cara membuat file dari terminal berulang satu set kata tanpa batas?

19

Bagaimana cara membuat file dari terminal berulang satu set kata tanpa batas? Saya membutuhkannya untuk membuat file besar untuk keperluan parsing seperti ukuran 2-4GB. Saat ini saya menyalin garis tempel secara manual ke file yang sama untuk menambah ukuran.

Nisheet
sumber
1
Saya ingin melihat jawaban berfungsi dengan file unix khusus, sehingga tidak akan menempati ruang itu. Apakah itu mungkin?
Délisson Junio
1
Maksudmu sesuatu yang benar-benar tak terbatas mkfifo huge.tmp; while true; do yes "a dummy line" > huge.tmp; done?
Boldewyn

Jawaban:

50

Ada cara mudah untuk mengulangi satu baris berkali-kali:

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

akan menghasilkan out.txt yang berisi 10.000 baris semua mengatakan "kami tidak punya pisang".


Untuk membatasi output untuk jumlah yang tepat byte, penggunaan head's -cpilihan bukan -n. Misalnya, ini menghasilkan tepat 10 kB teks:

yes we have no bananas | head -c 10000 > out.txt
hobbs
sumber
2
OP ingin berurusan dengan byte, bukan garis.
heemayl
4
Untuk menentukan batas dalam byte, cukup gunakan head -c 10000untuk 10 kB, bukan head -n 10000untuk 10k baris.
Byte Commander
@ ByteCommander ya, tapi itu tidak akan mencegah output terputus di tengah garis. Karena ukurannya tidak harus tepat, saya hanya akan mencari tahu jumlah garis untuk mendapatkan ukuran yang tepat, dan mengumpulkan :)
hobbs
1
Saya setuju, tetapi saya tidak yakin apakah itu akan menjadi masalah juga. OP tidak menentukan metode mana yang dia inginkan, tetapi jawaban Anda masih mengandung keduanya. Oh, dan selamat untuk menggandakan skor reputasi Anda hari ini :)
Byte Commander
@ ByteCommander ya, adil.
hobbs
10

Saya tidak bisa merekomendasikan tanpa batas mengulangi teks, tapi Anda bisa membuat file ~ 2GB teks berulang-ulang dengan python seperti begitu ...

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

Itu akan mencetak "halo dunia" 10 kali dan membuat baris baru, dan ulangi itu 20.000.000 kali, menulis hasilnya ke file bigfile. Jika semua karakter Anda adalah ASCII, maka masing-masing adalah satu byte, jadi hitung dengan tepat tergantung pada apa yang ingin Anda tulis ...

CPU Anda mungkin dimiliki. Saya kehabisan RAM jika saya mencoba melakukan lebih dari 10.000.000 baris ...

Saya menjalankan pemanggang roti

Zanna
sumber
OP ingin berurusan dengan byte, bukan garis.
heemayl
@ heemayl tentu saja jawaban Anda lebih baik, tetapi saya (secara samar-samar) telah menjelaskan bagaimana cara menghitung berapa banyak baris yang digunakan untuk mendapatkan byte yang diinginkan jadi saya tidak berpikir jawaban saya sama sekali tidak berguna
Zanna
4
@ Heemayl apa yang membuat Anda begitu yakin OP menginginkan byte? Pertanyaannya pada dasarnya menyatakan bahwa OP menginginkan file besar. Ukuran spesifiknya sangat kabur (2-4GB), jadi saya benar-benar ragu ada batas byte spesifik dalam pikiran.
terdon
1
@ heemayl ya, tapi itu sangat, sangat kabur. Pemahaman saya adalah bahwa OP hanya menginginkan file besar dan tidak peduli tentang ukuran yang tepat. Kalau tidak, mereka akan memberikan ukuran bukannya berbagai macam ukuran.
terdon
1
@cat ikr! <3python <3
Zanna
9

Perl memiliki xoperator yang hebat:

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

Jadi, sebagai solusi sederhana, Anda bisa menulis baris Anda beberapa juta kali. Misalnya, perintah ini membuat file 3G:

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

Jika Anda perlu menentukan ukuran pasti (2 GiB dalam hal ini), Anda dapat melakukan:

perl -e 'use bytes; while(length($str)<2<<20){ $str.="This is my line\n"} print "$str\n"' > file
terdon
sumber
Jika Anda sabar, Anda dapat menggunakan operator Perl 6 yang keren kecuali Perl 6 jauh, jauh, jauh, lebih lambat: D
cat
@ kucing apakah itu benar-benar? Saya belum menyentuh 6 sama sekali, tapi saya berasumsi itu hanya akan memiliki semua kebaikan ditambah dengan tambahan OO. Tahu kenapa lebih lambat?
terdon
1
Komentar saya sebagian besar fasih, tetapi saya menemukan pada awal tahun ini bahwa Perl 6 cukup lambat, dibandingkan dengan Python 3 yang secara kanonik jauh lebih lambat daripada Perl 5 (yang saya tidak uji). Pekerjaan difokuskan pada fitur dan kebenaran, belum kinerja, tetapi terdaftar sebagai tujuan untuk tahun 2015. Juga, Apakah Perl 6 cukup cepat untuk saya? .
kucing
(Di sisi lain, daftar fitur mengesankan untuk sedikitnya.)
cat
7
  • Masukkan set kata yang akan diulang dalam file misalnya source.txt. Dapatkan ukuran source.txt, dalam byte misalnya dengan:

     stat -c '%s' source.txt
    
  • Tentukan ukuran file tujuan misalnya destination.txt, 2 GB atau 4 GB atau apa pun. Konversi ukuran dalam byte.

  • Membagi ukuran file tujuan dengan ukuran file sumber. bashtidak dapat melakukan aritmatika floating point, tetapi tidak diperlukan dalam kasus ini.

  • Gunakan forkonstruksi untuk mengulang cat source.txtoperasi kali hasil divisi. Ini akan menjadi perkiraan terdekat dari ukuran file tujuan yang bisa Anda peroleh dengan pengulangan. Output dari operasi disimpan dalam destination.txt.

Misalnya, dengan asumsi source.txt30 byte, dan kami ingin membuat file 2 GB, kami perlu:

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

Di sini saya menetapkan batas atas oleh ((16777216/30)) pada saat inisialisasi; Anda bisa mendapatkan hasilnya dan menaruhnya di sini juga.

Operasi akan memakan waktu; semakin besar source.txt, semakin sedikit waktu yang dibutuhkan.

heemayl
sumber
1
Tidakkah ini membuka dan menutup destination.txtsekali untuk setiap iterasi dari loop?
Reinstate Monica - ζ--
@hexafraction Duh, sudah diperbaiki.
heemayl
6

Anda juga bisa menggunakan while-loop.

Contoh: Konten foo.txt(Ini adalah sumber Anda):

foo
bar
foobar

bar.txtkosong (Ini adalah file target Anda). Anda sekarang dapat menemukan loop berikut untuk menulis konten foo.txtbeberapa kali menjadi bar.txt:

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

Penjelasan:

  • stat --format "%s" bar.txtmenampilkan ukuran bar.txtdalam byte.
  • while [ $(stat --format "%s" bar.txt) -lt 150 ] tindakan berikut akan diulangi sampai ukuran target (dalam hal ini 150 byte) tercapai.
  • cat foo.txt >> bar.txttambahkan konten foo.txtkebar.txt
Wayne_Yux
sumber
4

pertama-tama jalankan perintah:

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

akan membuat file di jalur ukuran bs * menghitung byte acak, dalam kasus kami 2048 * 10 = 20Kb. yang dapat diubah sesuai kebutuhan.

cat - > file.txt

Perintah ini mengalihkan STDIN ke file, jadi Anda harus memasukkan dua baris dan kemudian tekan Ctrl + D. Maka Anda perlu menjalankan perintah berikut:

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

Di mana n adalah bilangan bulat. Ini akan membuat file dengan 2 ^ (n +1) baris di dalamnya, dengan menduplikasi dua baris asli Anda. Jadi untuk membuat file dengan 16 baris yang akan Anda lakukan:

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

Berikut ini beberapa angka untuk Anda mulai:

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
sumber
2
OP ingin berurusan dengan byte, bukan garis.
heemayl
OP juga menjaga jalur untuk mengisi file. dan perintah pertama saya sudah membuat file sesuai byte memori yang diperlukan.
Avani badheka
@ heemayl karakter baris baru masih menempati byte, sama dengan komentar saya sebelumnya. Itu karakter yang sah. Namun, OP memang menentukan kata-kata , Avani, jadi saya tidak berpikir teknik / dev / urandom Anda menjawab pertanyaan mereka.
Mike S
Tergantung pada / dev / urandom, apakah Anda mencoba beberapa byte acak. Bahkan Anda dapat memilih sendiri beberapa file yang berisi banyak byte data.
Avani badheka
4

FIFO mungkin adalah yang Anda cari. Alih-alih memanggil program Anda dengan file yang diberikan, Anda dapat mengikat hasil dari perintah shell untuk itu melalui proses subtitusi dan program akan melihat hasilnya sebagai file plaintext. Keuntungannya di sini adalah bahwa Anda tidak lagi dibatasi oleh ruang disk Anda, sehingga Anda dapat mencapai ukuran file yang tidak mungkin sebaliknya, asalkan program Anda tidak perlu buffer seluruh file terlebih dahulu dan hanya dapat menguraikannya baris demi baris. Misalnya, menggunakan balasan @hobbs untuk menghasilkan konten:

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

Ini meminjamkan saya file 95 gigabytes (menurut wc) tanpa biaya dalam ruang HDD dan hampir tidak ada RAM, hanya cukup untuk buffer apa perintah kembali sebelum dibaca. Ini hampir mendekati "tanpa batas" seperti yang akan Anda dapatkan.

Santo Guevarra
sumber