จะสร้างไฟล์จากเทอร์มินัลซ้ำชุดคำได้อย่างไร?


19

จะสร้างไฟล์จากเทอร์มินัลซ้ำชุดคำได้อย่างไร? ฉันต้องการมันเพื่อสร้างไฟล์ขนาดใหญ่สำหรับการแยกวิเคราะห์เช่นขนาด 2-4GB ขณะนี้ฉันกำลังคัดลอกบรรทัดวางลงในไฟล์เดียวกันด้วยตนเองเพื่อเพิ่มขนาด


1
ฉันต้องการเห็นคำตอบที่ทำงานกับไฟล์ยูนิกซ์พิเศษดังนั้นมันจะไม่ใช้พื้นที่นั้นจริงๆ เป็นไปได้ไหม
Délisson Junio

1
คุณหมายถึงบางสิ่งที่ไม่มีที่สิ้นสุดอย่างแท้จริงเช่นmkfifo huge.tmp; while true; do yes "a dummy line" > huge.tmp; done?
Boldewyn

คำตอบ:


50

มีวิธีง่าย ๆ ในการทำซ้ำหลาย ๆ แถว:

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

จะส่งผลให้ out.txt มี 10,000 บรรทัดทั้งหมดพูดว่า "เราไม่มีกล้วย"


เพื่อ จำกัด การออกไปเป็นจำนวนที่แน่นอนของไบต์ใช้head's ตัวเลือกแทน-c -nตัวอย่างเช่นสิ่งนี้จะสร้างข้อความขนาด 10 kB:

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

2
OP ต้องการจัดการกับไบต์ไม่ใช่บรรทัด
heemayl

4
หากต้องการระบุขีด จำกัด เป็นไบต์ให้ใช้เพียงhead -c 1000010 kB แทนที่จะhead -n 10000เป็น 10k lines
ผู้บัญชาการไบต์

@ ByteCommander ใช่ แต่นั่นจะไม่ป้องกันไม่ให้เอาต์พุตถูกตัดกลางบรรทัด ตั้งแต่ขนาดไม่จำเป็นต้องมีความแม่นยำผมก็จะคิดออกจำนวนของสายที่จะได้ขนาดที่เหมาะสมและรอบขึ้น :)
ฮอบส์

1
ฉันเห็นด้วย แต่ฉันไม่แน่ใจว่าจะเป็นปัญหาหรือไม่ OP ไม่ได้ระบุวิธีการที่เขาต้องการ แต่คำตอบของคุณยังคงมีทั้งสองอย่าง โอ้และขอแสดงความยินดีกับการเพิ่มคะแนนชื่อเสียงของคุณเป็นสองเท่าในวันนี้ :)
ผู้บัญชาการ Byte

@ ByteCommander อ๋อยุติธรรม
ฮอบส์

10

ฉันไม่สามารถแนะนำการทำซ้ำข้อความแบบไม่จำกัดได้ แต่คุณสามารถสร้างไฟล์ซ้ำขนาด ~ 2GB กับไพ ธ อนได้ ...

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

ที่จะพิมพ์ "Hello World" 10 ครั้งและทำให้เส้นใหม่และทำซ้ำที่ 20,000,000 bigfileครั้งการเขียนผลไปยังแฟ้ม หากตัวอักษรทั้งหมดของคุณเป็น ASCII ละก็เป็นหนึ่งไบต์ดังนั้นคำนวณอย่างเหมาะสมโดยขึ้นอยู่กับสิ่งที่คุณต้องการเขียน ...

ซีพียูของคุณอาจเป็นเจ้าของ ฉันหมด RAM ถ้าฉันพยายามทำมากกว่า 10,000,000 บรรทัด ...

ฉันใช้เครื่องปิ้งขนมปัง


OP ต้องการจัดการกับไบต์ไม่ใช่บรรทัด
heemayl

@heemayl แน่นอนคำตอบของคุณจะดีกว่า แต่ผมได้ (ราง) อธิบายวิธีการคำนวณจำนวนสายที่จะใช้ในการรับไบต์ที่ต้องการดังนั้นผมจึงไม่คิดว่าคำตอบของฉันคือไร้ประโยชน์อย่างเต็มที่
Zanna

4
@ heemayl อะไรที่ทำให้คุณแน่ใจว่า OP ต้องการไบต์? คำถามหลักระบุว่า OP ต้องการไฟล์ขนาดใหญ่ ขนาดที่เฉพาะเจาะจงนั้นคลุมเครือมาก (2-4GB) ดังนั้นฉันสงสัยว่าจริงๆแล้วมันมีข้อ จำกัด ของไบต์ที่เฉพาะเจาะจง
terdon

1
@ heemayl ใช่ แต่นั่นคลุมเครือมาก ความเข้าใจของฉันคือว่า OP ต้องการไฟล์ขนาดใหญ่และไม่สนใจขนาดที่แน่นอน มิฉะนั้นพวกเขาจะได้รับขนาดแทนขนาดที่ใหญ่มาก
terdon

1
@cat ikr! <3python <3
Zanna

9

Perl มีตัวxดำเนินการที่ดี:

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

ดังนั้นในการแก้ปัญหาง่ายๆคุณสามารถเขียนบรรทัดของคุณสองสามล้านครั้ง ตัวอย่างเช่นคำสั่งนี้สร้างไฟล์ 3G:

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

หากคุณต้องการระบุขนาดที่แน่นอน (2 GiB ในกรณีนี้) คุณสามารถทำได้:

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

หากคุณอดทนคุณสามารถใช้ตัวดำเนินการ Perl 6 ที่ยอดเยี่ยมยกเว้น Perl 6 มีมากมากมากช้ากว่ามาก: D
cat

@cat มันเป็นเรื่องจริงเหรอ? ฉันยังไม่ได้แตะ 6 เลย แต่ฉันคิดว่ามันน่าจะมีคุณความดีทั้งหมดบวกกับความพิเศษ OO ความคิดใด ๆ ที่ว่าทำไมมันช้าลง?
terdon

1
ความคิดเห็นของฉันส่วนใหญ่กะล่อน แต่ฉันพบว่าต้นปีนี้ที่ Perl 6 ค่อนข้างช้าเมื่อเทียบกับ Python 3 ซึ่งช้ากว่า Perl 5 มาก (ซึ่งฉันไม่ได้ทดสอบ) งานมุ่งเน้นไปที่คุณสมบัติและความถูกต้อง แต่ยังไม่ได้ประสิทธิภาพ แต่มันถูกระบุว่าเป็นเป้าหมายสำหรับปี 2558 นอกจากนี้Perl 6 ยังเร็วพอสำหรับฉันหรือไม่ .
แมว

(ในทางกลับกันรายการคุณสมบัติน่าประทับใจที่จะพูดน้อยที่สุด)
cat

7
  • source.txtใส่ชุดของคำพูดที่จะต้องทำซ้ำในเช่นไฟล์ รับขนาดของsource.txt, เป็นไบต์เช่นโดย:

     stat -c '%s' source.txt
    
  • ตัดสินใจขนาดของไฟล์ปลายทางเช่นdestination.txt2 GB หรือ 4 GB หรืออะไรก็ตาม แปลงขนาดเป็นไบต์

  • แบ่งขนาดไฟล์ปลายทางตามขนาดไฟล์ต้นฉบับ bashไม่สามารถคำนวณเลขทศนิยมได้ แต่ไม่จำเป็นในกรณีนี้

  • ใช้forโครงสร้างเพื่อทำซ้ำการcat source.txtดำเนินการครั้งผลหาร นี่จะเป็นค่าประมาณขนาดไฟล์ปลายทางที่ใกล้ที่สุดที่คุณสามารถทำได้โดยการทำซ้ำ destination.txtผลลัพธ์ของการดำเนินการจะถูกบันทึกไว้ใน

ตัวอย่างเช่นสมมติว่าsource.txtมีขนาด 30 ไบต์และเราต้องการสร้างไฟล์ 2 GB เราต้องการ:

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

ที่นี่ฉันกำลังตั้งค่าขีด จำกัด บนโดย((16777216/30))ในเวลาเริ่มต้น คุณสามารถรับผลลัพธ์และนำไปวางไว้ที่นี่ได้เช่นกัน

การดำเนินการจะใช้เวลาพอสมควร ยิ่งใช้source.txtเวลามากเท่าใด


1
สิ่งนี้ไม่เปิดและปิดdestination.txtหนึ่งครั้งสำหรับการวนซ้ำทุกครั้งหรือไม่
Reinstate Monica - ζ--

@hexafraction Duh แก้ไขแล้ว
heemayl

6

คุณยังสามารถใช้while-loop

ตัวอย่าง: เนื้อหาของfoo.txt(นี่คือแหล่งที่มาของคุณ):

foo
bar
foobar

bar.txtว่างเปล่า (นี่คือไฟล์เป้าหมายของคุณ) ตอนนี้คุณสามารถวนรอบต่อไปนี้เพื่อเขียนเนื้อหาfoo.txtหลาย ๆ ครั้งลงในbar.txt:

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

คำอธิบาย:

  • stat --format "%s" bar.txtแสดงขนาดเป็นbar.txtไบต์
  • while [ $(stat --format "%s" bar.txt) -lt 150 ] การดำเนินการต่อไปนี้จะทำซ้ำจนกว่าจะถึงขนาดเป้าหมาย (ในกรณีนี้ 150 ไบต์)
  • cat foo.txt >> bar.txtต่อท้ายเนื้อหาของfoo.txtถึงbar.txt

4

แรกของไฟคำสั่ง:

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

จะสร้างไฟล์บนพา ธ ของขนาด bs * นับจำนวนสุ่มในกรณีของเรา 2048 * 10 = 20Kb ที่สามารถเปลี่ยนแปลงได้ตามความต้องการ

cat - > file.txt

คำสั่งนี้จะเปลี่ยนเส้นทาง STDIN ไปยังไฟล์ดังนั้นคุณจะต้องป้อนสองบรรทัดแล้วกด Ctrl + D จากนั้นคุณจะต้องเรียกใช้คำสั่งต่อไปนี้:

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

โดยที่ n เป็นจำนวนเต็ม วิธีนี้จะสร้างไฟล์ที่มี 2 ^ (n + 1) บรรทัดในไฟล์โดยทำซ้ำสองบรรทัดเดิม ดังนั้นในการสร้างไฟล์ที่มี 16 บรรทัดคุณจะทำ:

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

ต่อไปนี้เป็นตัวเลขเพิ่มเติมเพื่อให้คุณเริ่มต้น:

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 ต้องการจัดการกับไบต์ไม่ใช่บรรทัด
heemayl

OP ยังคงจัดการกับบรรทัดสำหรับการเติมไฟล์ และคำสั่งแรกของฉันสร้างแล้วไฟล์ตามหน่วยความจำไบต์ที่ต้องการ
Avani badheka

@heemayl อักขระขึ้นบรรทัดใหม่ยังคงใช้งานไบต์เช่นเดียวกับความคิดเห็นก่อนหน้าของฉัน มันเป็นตัวละครที่ถูกกฎหมาย อย่างไรก็ตาม OP ได้ระบุคำว่า Avani ดังนั้นฉันไม่คิดว่าเทคนิค / dev / urandom ของคุณจะตอบคำถามของพวกเขา
Mike S

ขึ้นอยู่กับ / dev / urandom ไม่ว่าคุณจะพยายามสุ่มไบท์ แม้คุณสามารถเลือกไฟล์ของคุณเองที่มีข้อมูลจำนวนมาก
Avani badheka

4

FIFO อาจเป็นสิ่งที่คุณกำลังมองหา แทนที่จะเรียกโปรแกรมของคุณด้วยไฟล์ที่กำหนดคุณสามารถผูกผลลัพธ์ของคำสั่งเชลล์ไปที่คำสั่งย่อยผ่านกระบวนการลบคำบรรยายของกระบวนการและโปรแกรมจะเห็นเอาต์พุตของมันเป็นไฟล์ข้อความธรรมดา ข้อดีที่นี่คือคุณไม่ได้ถูก จำกัด ด้วยพื้นที่ว่างในดิสก์ของคุณอีกต่อไปดังนั้นคุณสามารถเข้าถึงขนาดไฟล์ที่เป็นไปไม่ได้เป็นอย่างอื่นตราบใดที่โปรแกรมของคุณไม่จำเป็นต้องบัฟเฟอร์ไฟล์ทั้งหมดก่อนและสามารถแยกมันทีละบรรทัด ตัวอย่างเช่นการใช้ @hobbs 'ตอบกลับเพื่อสร้างเนื้อหา:

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

สิ่งนี้จะให้ฉันไฟล์ 95 กิกะไบต์ (ตาม wc) โดยไม่มีค่าใช้จ่ายในพื้นที่ว่างบนฮาร์ดดิสก์และแทบ RAM ใด ๆ เพียงพอที่จะบัฟเฟอร์สิ่งที่คำสั่งส่งคืนก่อนที่จะได้รับการอ่าน นี่ใกล้เคียงกับ "อนันต์" อย่างที่คุณจะได้รับ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.