Làm thế nào để tạo một tập tin từ thiết bị đầu cuối lặp lại một tập hợp các từ vô hạn?


19

Làm thế nào để tạo một tập tin từ thiết bị đầu cuối lặp lại một tập hợp các từ vô hạn? Tôi cần nó để tạo một tệp lớn cho các mục đích phân tích cú pháp như kích thước 2-4GB. Hiện tại tôi đang sao chép thủ công các dòng dán vào cùng một tệp để tăng kích thước.


1
Tôi muốn thấy một câu trả lời làm việc với các tệp unix đặc biệt, vì vậy nó sẽ không thực sự chiếm không gian đó. Điều đó có thể không?
Délisson Junio

1
Bạn có nghĩa là một cái gì đó thực sự vô hạn như thế mkfifo huge.tmp; while true; do yes "a dummy line" > huge.tmp; donenào?
Boldewyn

Câu trả lời:


50

Có một cách dễ dàng để lặp lại một dòng nhiều lần:

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

sẽ dẫn đến out.txt chứa 10.000 dòng tất cả nói rằng "chúng tôi không có chuối".


Để hạn chế sản lượng để một con số chính xác của byte, sử dụng head's -clựa chọn thay vì -n. Ví dụ: điều này tạo ra chính xác 10 kB văn bản:

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

2
OP muốn xử lý byte, không phải dòng.
heemayl

4
Để chỉ định giới hạn tính bằng byte, chỉ cần sử dụng head -c 10000cho 10 kB thay vì head -n 10000cho 10k dòng.
Chỉ huy Byte

@ByteCommander có, nhưng điều đó sẽ không ngăn chặn đầu ra bị cắt giữa dòng. Vì kích thước không cần phải chính xác, tôi chỉ cần tìm ra số lượng dòng để có kích thước phù hợp và làm tròn lên :)
hobbs

1
Tôi đồng ý, nhưng tôi cũng không chắc đó có phải là vấn đề không. OP không chỉ định phương pháp nào anh ta muốn, nhưng câu trả lời của bạn vẫn chứa cả hai. Ồ, và chúc mừng bạn đã nhân đôi số điểm danh tiếng của bạn ngày hôm nay :)
Chỉ huy Byte

@ByteCommander yep, công bằng.
hobbs

10

Tôi không thể khuyên bạn nên lặp lại văn bản vô hạn , nhưng bạn có thể tạo một tệp ~ 2GB văn bản lặp lại với python như vậy ...

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

Điều đó sẽ in "hello world" 10 lần và tạo một dòng mới, và lặp lại 20.000.000 lần đó, ghi kết quả vào tệp bigfile. Nếu tất cả các ký tự của bạn là ASCII, thì mỗi ký tự là một byte, vì vậy hãy tính toán một cách thích hợp tùy thuộc vào nội dung bạn muốn viết ...

Cpu của bạn có thể được sở hữu. Tôi hết RAM nếu tôi thử thực hiện hơn 10.000.000 dòng ...

Tôi đang chạy máy nướng bánh mì


OP muốn xử lý byte, không phải dòng.
heemayl

@heemayl tất nhiên câu trả lời của bạn tốt hơn, nhưng tôi đã (giải thích một cách mơ hồ) cách tính toán có bao nhiêu dòng để sử dụng byte mong muốn vì vậy tôi không nghĩ câu trả lời của mình hoàn toàn vô dụng
Zanna

4
@heemayl điều gì khiến bạn chắc chắn OP muốn byte? Câu hỏi về cơ bản nói rằng OP muốn một tệp lớn. Kích thước cụ thể rất mơ hồ (2-4 GB), vì vậy tôi thực sự nghi ngờ có một giới hạn byte cụ thể trong tâm trí.
terdon

1
@heemayl vâng, nhưng điều đó rất, rất mơ hồ. Tôi hiểu rằng OP chỉ muốn một tệp lớn và không quan tâm đến kích thước chính xác. Mặt khác, họ đã đưa ra một kích thước thay vì một phạm vi kích thước khổng lồ như vậy.
terdon

1
@cat ikr! <3python <3
Zanna

9

Perl có xtoán tử tiện lợi :

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

Vì vậy, như một giải pháp đơn giản, bạn có thể viết dòng của mình vài triệu lần. Ví dụ: lệnh này đã tạo một tệp 3G:

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

Nếu bạn cần chỉ định một kích thước chính xác (2 GiB trong trường hợp này), bạn có thể làm:

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

Nếu bạn kiên nhẫn, bạn có thể sử dụng các toán tử Perl 6 thú vị, ngoại trừ Perl 6 thì nhiều, nhiều, nhiều, chậm hơn nhiều: D
cat

@cat có thật không? Tôi chưa chạm vào 6, nhưng tôi đã cho rằng nó chỉ có tất cả sự tốt đẹp cộng với các tính năng bổ sung OO. Bất cứ ý tưởng tại sao nó chậm hơn?
terdon

1
Nhận xét của tôi chủ yếu là hào nhoáng, nhưng tôi nhận thấy vào đầu năm nay rằng Perl 6 khá chậm, so với Python 3 chậm hơn nhiều so với Perl 5 (mà tôi không thử nghiệm). Công việc tập trung vào các tính năng và tính chính xác, chưa phải là hiệu suất, nhưng nó được liệt kê như một mục tiêu cho năm 2015. Ngoài ra, Perl 6 có đủ nhanh với tôi không? .
mèo

(Mặt khác, danh sách các tính năng rất ấn tượng để nói là ít nhất.)
mèo

7
  • Đặt tập hợp các từ được lặp lại trong một tập tin, vd source.txt. Lấy kích thước của source.txt, tính bằng byte, ví dụ:

     stat -c '%s' source.txt
    
  • Quyết định kích thước của tệp đích destination.txt, ví dụ: 2 GB hoặc 4 GB hoặc bất cứ điều gì. Chuyển đổi kích thước theo byte.

  • Chia kích thước tệp đích theo kích thước tệp nguồn. bashkhông thể thực hiện số học dấu phẩy động, nhưng trong trường hợp này không cần thiết.

  • Sử dụng một forcấu trúc để lặp lại một cat source.txthoạt động thời gian kết quả phân chia. Đây sẽ là gần đúng nhất về kích thước tệp đích bạn có thể nhận được bằng cách lặp lại. Đầu ra của hoạt động được lưu trong destination.txt.

Ví dụ: giả sử source.txtlà 30 byte và chúng tôi muốn tạo tệp 2 GB, chúng tôi cần:

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

Ở đây tôi đang đặt giới hạn trên bằng ((16777216/30))tại thời điểm khởi tạo; bạn có thể nhận được kết quả và đặt nó ở đây quá.

Các hoạt động sẽ mất một thời gian; càng lớn source.txt, càng cần ít thời gian.


1
Điều này không mở và đóng destination.txtmột lần cho mỗi lần lặp của vòng lặp sao?
Phục hồi Monica - ζ--

@hexafraction Duh, đã sửa.
heemayl

6

Bạn cũng có thể sử dụng một while-loop.

Ví dụ: Nội dung của foo.txt(Đây là nguồn của bạn):

foo
bar
foobar

bar.txttrống rỗng (Đây là tệp mục tiêu của bạn). Bây giờ bạn có thể rn vòng lặp sau để viết nội dung của foo.txtnhiều lần vào bar.txt:

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

Giải trình:

  • stat --format "%s" bar.txthiển thị kích thước tính bar.txtbằng byte.
  • while [ $(stat --format "%s" bar.txt) -lt 150 ] các hành động sau sẽ được lặp lại cho đến khi đạt được kích thước đích (trong trường hợp này là 150 byte).
  • cat foo.txt >> bar.txtthêm nội dung của foo.txtđểbar.txt

4

đầu tiên của lệnh:

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

sẽ tạo một tệp trên đường dẫn có kích thước bs * đếm số byte ngẫu nhiên, trong trường hợp của chúng tôi là 2048 * 10 = 20Kb. có thể được thay đổi theo yêu cầu.

cat - > file.txt

Lệnh này chuyển hướng STDIN thành một tệp, vì vậy bạn sẽ cần nhập hai dòng và sau đó nhấn Ctrl + D. Sau đó, bạn sẽ cần chạy lệnh sau:

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

Trong đó n là một số nguyên. Điều này sẽ tạo một tệp có 2 ^ (n + 1) dòng trong đó, bằng cách sao chép hai dòng ban đầu của bạn. Vì vậy, để tạo một tệp có 16 dòng bạn sẽ làm:

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

Dưới đây là một số số khác để bạn bắt đầu:

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 muốn xử lý byte, không phải dòng.
heemayl

OP cũng đang giữ dòng đối phó để điền vào tệp. và lệnh đầu tiên của tôi đã tạo tệp theo byte yêu cầu của bộ nhớ.
Avani badheka

@heemayl ký tự dòng mới vẫn chiếm một byte, giống như nhận xét trước đó của tôi. Đó là một nhân vật hợp pháp. Tuy nhiên, OP đã chỉ định từ , Avani, vì vậy tôi không nghĩ rằng kỹ thuật / dev / urandom của bạn trả lời câu hỏi của họ.
Mike S

Nó phụ thuộc vào / dev / urandom, cho dù bạn đang thử một số byte ngẫu nhiên. Thậm chí bạn có thể chọn một số tệp của riêng mình chứa nhiều byte dữ liệu đó.
Avani badheka

4

FIFO có lẽ là những gì bạn đang tìm kiếm. Thay vì gọi chương trình của bạn bằng một tệp đã cho, bạn có thể kết quả kết quả của lệnh shell với nó thông qua quy trình phụ và chương trình sẽ xem kết quả đầu ra của nó dưới dạng tệp văn bản gốc. Ưu điểm ở đây là bạn không còn bị giới hạn bởi dung lượng ổ đĩa của mình, vì vậy bạn có thể tiếp cận các tệp có thể là điều không thể, miễn là chương trình của bạn không cần phải đệm toàn bộ tệp trước và chỉ có thể phân tích từng dòng. Ví dụ: sử dụng trả lời của @hobbs để tạo nội dung:

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

Điều này cho tôi mượn một tệp 95 gigabyte (theo wc) miễn phí trong không gian ổ cứng và hầu như không có RAM, chỉ đủ để đệm những gì lệnh trả về trước khi đọc. Đây là gần như "vô tận" như bạn sẽ nhận được.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.