วิธีที่ดีที่สุดในการเข้าร่วมไฟล์อีกครั้งหลังจากแยกพวกเขาคืออะไร?


73

หากฉันมีไฟล์ขนาดใหญ่และจำเป็นต้องแยกเป็น 100 เมกาไบต์ฉันจะทำ

split -b 100m myImage.iso

ที่มักจะให้อะไรฉันชอบ

xaa
xab
xac
xad

และเพื่อให้พวกเขากลับมารวมกันฉันได้ใช้

cat x* > myImage.iso

ดูเหมือนว่าควรมีวิธีที่มีประสิทธิภาพมากกว่าการอ่านแต่ละบรรทัดของรหัสในกลุ่มของไฟล์ด้วยcatและเปลี่ยนเส้นทางผลลัพธ์ไปยังไฟล์ใหม่ เช่นเดียวกับการเปิดไฟล์สองไฟล์ให้ลบEOFเครื่องหมายออกจากไฟล์แรกและเชื่อมต่อไฟล์เหล่านั้นโดยไม่ต้องผ่านเนื้อหาทั้งหมด

Windows / DOS มีคำสั่ง copy สำหรับไฟล์ไบนารี วิธีใช้ระบุว่าคำสั่งนี้ถูกออกแบบมาเพื่อให้สามารถรวมหลายไฟล์ได้ มันทำงานร่วมกับไวยากรณ์นี้: ( /bสำหรับโหมดไบนารี)

copy /b file1 + file2 + file3 outputfile

มีบางสิ่งที่คล้ายกันหรือเป็นวิธีที่ดีกว่าในการเข้าร่วมไฟล์ขนาดใหญ่บน Linux มากกว่า cat?

ปรับปรุง

ดูเหมือนว่าcatเป็นวิธีที่ถูกต้องและเป็นวิธีที่ดีที่สุดในการเข้าร่วมไฟล์ ดีใจที่รู้ว่าฉันใช้คำสั่งที่ถูกต้องมาตลอด :) ขอบคุณทุกคนสำหรับความคิดเห็นของคุณ


22
หมายเหตุด้านข้าง: อย่าใช้งานได้ดีกว่าcat x*เนื่องจากลำดับของไฟล์ขึ้นอยู่กับการตั้งค่าภาษาของคุณ เริ่มต้นพิมพ์ได้cat xดีกว่ากดEscแล้ว*- คุณจะเห็นลำดับของไฟล์ที่ขยายและสามารถจัดเรียงใหม่ได้
rozcietrzewiacz

16
แทนที่จะcat x*พิจารณาการขยายตัวของ shell brace cat xa{a..g}ซึ่งจะขยายลำดับที่ระบุเป็นcat xaa xab xac xad xae xaf xag
Peter.O

3
@rozcietrzewiacz - คุณสามารถยกตัวอย่างว่าฉันจะปรับการตั้งค่าสถานที่ที่จะทำลายได้cat x*อย่างไร การตั้งค่าตำแหน่งที่ตั้งใหม่จะไม่ส่งผลกระทบsplitดังนั้นหากsplitและcat x*ถูกใช้ในระบบเดียวกันพวกเขาจะใช้งานได้หรือไม่
cwd

3
"เปิดไฟล์สองไฟล์ลบเครื่องหมาย EOF ออกจากไฟล์แรกและเชื่อมต่อโดยไม่ต้องผ่านเนื้อหาทั้งหมด" ... ดูเหมือนว่าคุณจะต้องคิดค้นระบบไฟล์ใหม่เพื่อทำสิ่งที่คุณต้องการ
JoelFan

6
@cwd: มองไปที่split.cใน GNU coreutils, static char const *suffix_alphabet = "abcdefghijklmnopqrstuvwxyz";คำต่อท้ายจะถูกสร้างขึ้นมาจากอาร์เรย์คงที่ของตัวอักษร: ส่วนต่อท้ายจะไม่ได้รับผลกระทบจากภาษา (แต่ฉันไม่คิดว่าสถานที่ใด ๆ ที่มีสติจะเรียงลำดับตัวอักษรพิมพ์เล็กใหม่ได้แม้กระทั่ง EBCDIC ก็ยังคงรักษาคำสั่งมาตรฐานไว้)
Keith Thompson

คำตอบ:


50

นั่นเป็นเพียงสิ่งที่catถูกสร้างขึ้นมาเพื่อ เนื่องจากเป็นหนึ่งในเครื่องมือ GNU ที่เก่าแก่ที่สุดฉันคิดว่ามันไม่น่าเป็นไปได้มากที่เครื่องมืออื่น ๆ จะทำงานได้เร็วขึ้น / ดีขึ้น และมันไม่ได้เป็นท่อ - มันเป็นเพียงการเปลี่ยนเส้นทางของผลผลิต


cat x, then press Escเคล็ดลับที่คุณกล่าวถึงเป็นระเบียบ .. ฉันได้รับการมองหาสิ่งที่ต้องการที่ขอบคุณ ... ความคิดเห็นที่ดีและคำตอบที่ดี
Peter.O

2
ไม่เป็นไร :) นอกจากนี้เมื่อคุณมีรายการไฟล์ในบรรทัดคำสั่งคุณสามารถใช้Ctrl+Wเพื่อตัดคำแล้วCtrl+Yวางมัน
rozcietrzewiacz

cat หมายถึง "concatenate"
JoelFan

4
.. และ "catenate" มาจากคำภาษาละติน "catena" ซึ่งแปลว่า "a chain" .. การต่อเชื่อมเข้าด้วยกันเป็นการเชื่อมโยงของ chain ... (และอีกเล็กน้อยนอกหัวข้อโค้ง catenaryยังมาจาก "catena" มันเป็นวิธีที่ห่วงโซ่แขวน)
Peter.O

19

ภายใต้ประทุน

ไม่มีวิธีที่มีประสิทธิภาพมากกว่าการคัดลอกไฟล์แรกจากนั้นคัดลอกไฟล์ที่สองหลังจากนั้นเป็นต้น ทั้ง DOS copyและcatทำอย่างนั้น

แต่ละไฟล์ถูกเก็บไว้เป็นอิสระจากไฟล์อื่น ๆ บนดิสก์ เกือบทุกระบบไฟล์ที่ออกแบบมาเพื่อเก็บข้อมูลบนอุปกรณ์ที่มีลักษณะเหมือนดิสก์ทำงานโดยบล็อก นี่คือการนำเสนอที่ง่ายขึ้นอย่างมากในสิ่งที่เกิดขึ้น: ดิสก์แบ่งออกเป็นบล็อกพูด 1kB และสำหรับแต่ละไฟล์ที่ระบบปฏิบัติการจัดเก็บรายการบล็อกที่ทำขึ้น ไฟล์ส่วนใหญ่มีจำนวนบล็อกไม่เต็มจำนวนดังนั้นบล็อกสุดท้ายจึงมีเพียงบางส่วนเท่านั้น ในทางปฏิบัติระบบไฟล์มีการปรับแต่งมากมายเช่นการแชร์บล็อกบางส่วนสุดท้ายระหว่างไฟล์หลาย ๆ ไฟล์หรือจัดเก็บ“ บล็อก 46798 ถึง 47913” มากกว่า“ บล็อก 46798 บล็อก 46799, …” เมื่อระบบปฏิบัติการต้องการสร้างไฟล์ใหม่มันจะค้นหาบล็อกว่าง บล็อกไม่จำเป็นต้องต่อเนื่องกัน: ถ้าบล็อก 4, 5, 98 และ 178 นั้นฟรีคุณยังสามารถเก็บไฟล์ 4kB ได้

คุณสามารถรองรับบล็อกบางส่วนในไฟล์กลางได้ แต่นั่นจะเพิ่มความซับซ้อนอย่างมากโดยเฉพาะอย่างยิ่งเมื่อเข้าถึงไฟล์ที่ไม่ต่อเนื่อง: เพื่อข้ามไปยัง 10340th ไบต์คุณไม่สามารถข้ามไปที่ 100 ไบต์ของบล็อกที่ 11 ได้อีกต่อไป เพื่อตรวจสอบความยาวของบล็อกที่สอดแทรกทุกอัน

เมื่อมีการใช้งานบล็อกคุณไม่สามารถเข้าร่วมสองไฟล์ได้เพราะโดยทั่วไปไฟล์แรกจะจบลงด้วยการบล็อกกลาง แน่นอนว่าคุณสามารถมีกรณีพิเศษได้เฉพาะเมื่อคุณต้องการลบทั้งสองไฟล์เมื่อทำการเชื่อมต่อ นั่นจะเป็นการจัดการที่เฉพาะเจาะจงสำหรับการดำเนินการที่หายาก การจัดการพิเศษดังกล่าวไม่ได้อยู่ในตัวของมันเองเพราะในระบบไฟล์ทั่วไปไฟล์จำนวนมากจะถูกเข้าถึงในเวลาเดียวกัน ดังนั้นหากคุณต้องการเพิ่มการปรับให้เหมาะสมคุณต้องคิดให้รอบคอบ: จะเกิดอะไรขึ้นถ้ากระบวนการอื่นกำลังอ่านไฟล์ใดไฟล์หนึ่งที่เกี่ยวข้อง จะเกิดอะไรขึ้นถ้ามีคนพยายามต่อ A และ B ในขณะที่บางคนกำลังต่อกัน A และ C? และอื่น ๆ สรุปแล้วการเพิ่มประสิทธิภาพที่หายากนี้จะเป็นภาระที่ยิ่งใหญ่

โดยรวมแล้วคุณไม่สามารถทำให้การเข้าร่วมไฟล์มีประสิทธิภาพมากขึ้นโดยไม่ต้องเสียสละที่สำคัญอื่น ๆ มันไม่คุ้มค่า.

เมื่อแยกและเข้าร่วม

splitและcatเป็นวิธีง่ายๆในการแยกและเข้าร่วมไฟล์ splitดูแลการสร้างไฟล์ที่มีชื่อเรียงตามลำดับตัวอักษรดังนั้นจึงcat *เหมาะสำหรับการเข้าร่วม

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

มีสาธารณูปโภคการบีบอัดที่ผลิตจดหมายเหตุหลายส่วนเช่นมีและzipsplit rar -vพวกเขาไม่ได้ unixy มากเพราะพวกเขาบีบอัดและแพ็ค (รวมหลายไฟล์เป็นหนึ่ง) นอกเหนือจากการแยก แต่สิ่งเหล่านี้มีประโยชน์ในการตรวจสอบว่าคุณมีชิ้นส่วนทั้งหมดและชิ้นส่วนนั้นเสร็จสมบูรณ์แล้ว


8

ดูเหมือนว่าควรมีวิธีที่มีประสิทธิภาพมากกว่าการวางเนื้อหาทั้งหมดผ่านระบบstdin/stdout

ยกเว้นว่าไม่ใช่สิ่งที่เกิดขึ้นจริง ๆ เชลล์กำลังเชื่อมต่อ stdout ของcat โดยตรงกับไฟล์ที่เปิดซึ่งหมายความว่า "กำลังผ่าน stdout" เหมือนกับการเขียนไปยังดิสก์


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

@cwd มันเป็นไปได้ที่จะออกแบบระบบไฟล์ที่คุณสามารถเข้าร่วมสองไฟล์ในแบบนั้น แต่มันจะทำให้การออกแบบระบบไฟล์มีความซับซ้อนอย่างมาก คุณต้องการปรับให้เหมาะสมสำหรับการดำเนินการนั้นโดยมีค่าใช้จ่ายในการทำภารกิจทั่วไปที่ซับซ้อนและช้ากว่ามาก
Gilles

@Gilles - มันน่าสนใจที่จะรู้เพิ่มเติมเกี่ยวกับรายละเอียดในระดับต่ำ สำหรับฉันการอ่านเซกเตอร์ทั้งหมดออกจากฮาร์ดดิสก์สำหรับไฟล์หลาย ๆ ไฟล์จากนั้นการดัมพ์มันกลับไปยังเซกเตอร์ที่ไม่ได้ใช้อื่น ๆ บนดิสก์นั้นดูเหมือนว่าไม่มีประสิทธิภาพ และฉันคิดว่าไฟล์ขนาดใหญ่จะต้องถูกจัดเก็บข้ามบล็อคของเซ็กเตอร์ฟรีหลาย ๆ ครั้งเพราะอาจมีบล็อกที่อยู่เคียงข้างไม่เพียงพอในการจัดเก็บ ดังนั้นในทางทฤษฎีคุณสามารถเข้าร่วมไฟล์เป็นไฟล์เดียวโดยลบเครื่องหมาย EOF และชี้ไปที่กลุ่มของเซกเตอร์เมื่อเริ่มต้นไฟล์ถัดไป * ระวังมีพลังดังนั้นฉันสงสัยว่ามีวิธีที่ดีกว่าแมว
cwd

@cwd ไม่มี“ เครื่องหมาย EOF” ไม่มีระบบไฟล์ที่ทันสมัยที่ใช้งานได้เพราะมันป้องกันไม่ให้อักขระบางตัวเกิดขึ้นในไฟล์ (หรือต้องใช้การเข้ารหัสที่ซับซ้อน) แต่แม้ว่าจะมีเครื่องหมาย EOF แต่ส่วนใหญ่แล้วคุณจะไม่มีไฟล์ที่ถูกต้องหลังจากนั้น
Gilles

ฉันหมายถึงแนวคิดของเครื่องหมาย EOF ไม่ใช่เครื่องหมาย EOF จริง มิฉะนั้นถ้าคุณดูที่บิตและไบต์ของไฟล์บนฮาร์ดไดรฟ์คุณจะรู้ได้อย่างไรว่ามันสิ้นสุดลงที่ใด? คุณระบุความยาวของไฟล์ที่จุดเริ่มต้นของไฟล์หรือไม่ ฉันกำลังพูดถึงสิ่งที่ระดับต่ำจริงๆ นั่นคือสิ่งที่คุณกำลังอ้างถึงเช่นกัน?
cwd

3

ฉันเคยมีปัญหานี้อย่างแน่นอน: ฉันต้องการที่จะเข้าร่วมไฟล์บางส่วน แต่มีพื้นที่ดิสก์ไม่เพียงพอที่จะเก็บไว้เป็นสองเท่า

ดังนั้นฉันจึงเขียนโปรแกรมมากมาย:

  • หนึ่งในการ "ดูด" ไฟล์โดยการอ่านส่งไปยัง stdout และหากเสร็จแล้วลบออก
  • และหนึ่งในการบัฟเฟอร์ข้อมูล "ในทันที"

สิ่งนี้ทำให้ฉันทำสิ่งที่ชอบ

partto sourcefile | mybuffer 128M >>cumufile

และทำให้การลบไฟล์ต้นฉบับในขณะที่ 128M ยังไม่ได้เขียน ค่อนข้างอันตรายเล็กน้อย แต่ถ้าข้อมูลนั้นไม่ได้มีค่าหรือมีอยู่ที่อื่นก็เป็นไปได้

หากจำเป็นฉันสามารถจัดหาแหล่งที่มา


0

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

$ mkfifo myImage.iso
$ cat xa{a..g} > myImage.iso &

และจากนั้นใช้myImage.isoตัวอย่างเช่น

$ md5sum myImage.iso

แม้ว่าแน่นอนว่าmyImage.isoเป็นไฟล์พิเศษ (ชื่อไปป์) และไม่ใช่ไฟล์ปกติดังนั้นอาจมีการใช้งานหรือไม่ขึ้นอยู่กับสิ่งที่คุณพยายามทำ


0

การแบ่งไฟล์

แยกตามขนาด

หากคุณต้องการแยกไฟล์ขนาดใหญ่เป็นไฟล์ขนาดเล็กและเลือกชื่อและขนาดของไฟล์เอาต์พุตขนาดเล็กนี่เป็นวิธี

split -b 500M videos\BigVideoFile.avi SmallFile.

ด้วยวิธีนี้คุณเลือกที่จะแยกไฟล์ขนาดใหญ่หนึ่งไฟล์เป็นส่วนเล็ก ๆ 500 MB นอกจากนี้คุณต้องการให้ชื่อของไฟล์ชิ้นส่วนคือ SmallFile โปรดทราบว่าคุณต้องมีจุดหลังชื่อไฟล์ ผลลัพธ์ควรสร้างไฟล์ใหม่เช่นนี้:

SmallFile.ab SmallFile.ad SmallFile.af SmallFile.ah SmallFile.aj
SmallFile.aa SmallFile.ac SmallFile.ae SmallFile.ag SmallFile.ai SmallFile.ak
...

แยกตามจำนวนบรรทัด

วิธีนี้คุณจะแบ่งไฟล์ข้อความเป็นไฟล์ขนาดเล็กลงได้ไม่เกิน 50 บรรทัด

split -l 50 text_to_split.txt

ผลลัพธ์ควรเป็นดังนี้:

xaa xab xac ...

แยกตามจำนวนไบต์

แยกเป็นไฟล์ขนาดเล็กด้วยขนาดไฟล์แบบกำหนดเองเป็นไบต์:

split -b 2048 BigFile.mp4

ผลที่ควรจะคล้ายกับเป็นผลมาจากspliting ตามจำนวนสาย

ไฟล์เข้าร่วม

คุณสามารถเข้าร่วมไฟล์ได้สองวิธี คนแรกคือ:

cat SmallFile.* > OutputBigVideoFile.avi

หรือด้วย:

cat SmallFile.?? > OutputBigVideoFile.avi

หมายเหตุ:เมื่อคุณเข้าร่วมไฟล์ไฟล์ขนาดเล็กไม่ควรได้รับความเสียหาย นอกจากนี้ไฟล์เล็ก ๆ (บางส่วน) ควรอยู่ในไดเรกทอรีเดียวกัน

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