บีบอัดไฟล์หลายไฟล์พร้อมกัน


27

ฉันมีมากกว่า 200 .zipไฟล์ในโฟลเดอร์เดียว ฉันไม่ต้องการขยายมันทีละอัน ฉันต้องการแยกข้อมูลเหล่านั้นโดยใช้คำสั่งเดียวหรือสคริปต์ วิธีการทำ

คำตอบ:


38

หากคุณต้องการคลายการบีบอัดข้อมูลแบบขนานคุณสามารถทำได้

for i in *zip; do unzip "$i" & done

อย่างไรก็ตามจะเปิดใช้งานกระบวนการ N สำหรับไฟล์ N. zip และอาจหนักมากในระบบของคุณ สำหรับวิธีการที่ควบคุมได้มากขึ้นการเรียกใช้กระบวนการแบบขนานเพียง 10 กระบวนการในแต่ละครั้งให้ลองสิ่งนี้:

find . -name '*.zip' -print0 | xargs -0 -I {} -P 10 unzip {}

หากต้องการควบคุมจำนวนกระบวนการแบบขนานที่เปิดใช้ให้เปลี่ยน-Pเป็นสิ่งที่คุณต้องการ หากคุณไม่ต้องการเรียกเก็บเงินคืนในไดเรกทอรีย่อยให้ทำเช่นนี้แทน:

find . -maxdepth 1 -name '*.zip' -print0 | xargs -0 -I {} -P 10 unzip {}

หรือคุณสามารถติดตั้งGNU ขนานตามที่แนะนำโดย @OleTange ในคอมเม้นต์และรัน

parallel unzip ::: *zip

3
การทำงานแบบขนานเป็นความคิดที่ดี แต่จะไม่ใช้ดิสก์ I / O เป็นคอขวดหลักหรือ
Paddy Landau

1
@ PaddyLandau ไม่แน่ใจฉันต้องตรวจสอบ มันจะขึ้นอยู่กับความเร็วของอัลกอริธึมการบีบอัดเทียบกับความเร็วของดิสก์ที่ฉันจินตนาการ
terdon

ใช้-execหรือแทนท่อไป-execdir xargsไม่เพียง แต่จะเข้าใจได้ง่ายขึ้น แต่ยังมีข้อผิดพลาดน้อยกว่าและใช้ทรัพยากรระบบน้อยลง find . -name '*.zip' -exec unzip {} ';'(คุณต้องพูดกึ่งลำไส้ใหญ่.)
ข้าวกุ๊บ

@PaddyLandau เหตุผลเดียวที่ฉันส่งไปยัง xargs คือการทำงานแบบขนานตามที่ OP ถาม -exec \;(คุณสามารถหนีเครื่องหมายอัฒภาคไม่จำเป็นต้องมีเครื่องหมายคำพูด) จะเรียกใช้แต่ละคำสั่งตามลำดับ -exec +ดีกว่า แต่มันจะไม่ทำงานที่นี่เพราะมันไม่unzipทำงาน
terdon

ฉันคิดว่าเราเข้าใจ OP แตกต่างกัน คุณอ่านเขาว่าต้องการมันแบบขนานในขณะที่ฉันเข้าใจเขาว่าหมายถึงคำสั่งเดียวแทนที่จะเป็นหลายคำสั่ง ดีเขามีวิธีการทั้งในปัจจุบัน :)
นากุ๊บ

17

ขนาน GNUคำสั่งมีความเหมาะสมดีกับชนิดของสิ่งนี้ หลังจาก:

$ sudo apt-get install parallel

แล้วก็

ls *.zip | parallel unzip

สิ่งนี้จะใช้คอร์มากเท่าที่คุณมีทำให้แต่ละคอร์ไม่ว่างด้วยการคลายซิปจนกว่าจะเสร็จสิ้น


เป็นความคิดที่ดีกว่าที่จะใช้echo *.zipแทนเพื่อป้องกันไม่ให้ชื่อแทนที่เป็นไปได้จากการแอบดูข้อมูลเพิ่มเติม อย่างไรก็ตามสิ่งนี้มีปัญหาเช่นเดียวกับคำตอบของ @ Guru แต่จะแบ่งตามชื่อไฟล์ที่มีช่องว่าง
nyuszika7h

1
@ nyuszika7h ตรงกันข้ามกับxargsGNU Parallel ไม่ได้ทำลายชื่อไฟล์ที่มีช่องว่าง / tab / quote เฉพาะในกรณีที่ชื่อไฟล์มีการขึ้นบรรทัดใหม่คุณจะต้องระมัดระวังเป็นพิเศษ ตัวอย่างเช่นโดยใช้:parallel unzip ::: *.zip
Ole Tange

@ nyuszika7h - นี่เป็นเหตุผลที่ดีที่จะหลีกเลี่ยงคำสั่งมาตรฐานทั้งนามแฝงและการเว้นวรรคในชื่อไฟล์
Wayne Conrad

@ nyuszika7h ใช้คือไม่ดีเท่าที่ใช้echo lsการลูบและการวนซ้ำเป็นสิ่งที่ปลอดภัยที่สุด
terdon

1
@NateEldredge ในขณะที่โอกาสนั้นยิ่งใหญ่กว่าในอดีตเมื่อระบบมีดิสก์แม่เหล็กเพียงแผ่นเดียว แต่ทุกวันนี้ด้วย RAID ที่มีแกนหมุนหลายตัวและแฟลชดิสก์ที่มีโอกาสน้อยกว่า สิ่งที่ดีที่สุดที่ต้องทำคือการวัดและดูว่าระบบของคุณทำงานอย่างไร เมื่อเร็ว ๆ นี้ฉันใช้ RAID 40 สปินเดิลซึ่งความขนานที่เหมาะสมที่สุดสำหรับกระบวนการหิวของ I / O คือ 10: มันไม่ได้เพิ่มความเร็วขึ้น 10 เท่า - เพียง 6x แต่น้อยกว่า 10 กระบวนการให้น้อยกว่า 6x
Ole Tange

12

คุณสามารถใช้คำสั่งต่อไปนี้:

เปลี่ยนไดเรกทอรีแรกในเทอร์มินัลเป็นไดเรกทอรีที่มีไฟล์. zip

cd /path

จากนั้นดำเนินการคำสั่งนี้เพื่อคลายซิปไฟล์. zip ทั้งหมด:

for z in *.zip; do unzip "$z"; done

10

หากคุณมี.zipไฟล์จำนวนมากในโฟลเดอร์ของคุณและคุณต้องการแตกไฟล์ทั้งหมดให้เปิดเทอร์มินัลแล้วไปที่โฟลเดอร์ของคุณโดยใช้:

cd <path_to_folder>

ตอนนี้ใช้คำสั่งนี้เพื่อขยาย.zipไฟล์ทั้งหมดของคุณ:

ls *.zip | xargs -n1 unzip

3
สิ่งนี้จะล้มเหลวหากชื่อไฟล์ใด ๆ มีช่องว่าง
terdon

1
ใช่คุณถูกต้อง.
g_p

เป็นความคิดที่ดีกว่าที่จะใช้echo *.zipแทนเพื่อป้องกันlsนามแฝงที่เป็นไปได้จากการแอบดูข้อมูลเพิ่มเติมอย่างไรก็ตามยังไม่สามารถแก้ไขปัญหาช่องว่าง
nyuszika7h

1
@OleTange ในกรณีที่คุณไม่ได้สังเกตเห็นฉันบอกว่ามันยังคงล้มเหลวในชื่อไฟล์ที่มีช่องว่างในพวกเขา
nyuszika7h

1
ไม่ต้องพึ่งพาเอาต์พุตจากlsสำหรับสคริปต์เนื่องจากเอาต์พุตไม่ได้ถูกกำหนดอย่างชัดเจนระหว่างเวอร์ชัน ให้ดูคำตอบจาก @terdon แทนเพราะมันจะแก้ปัญหาทั้งหมดของการแก้ปัญหานี้
Paddy Landau

6

คุณสามารถใช้ find with -execlike so,

find . -name "*.zip" -exec unzip {} \;

สิ่งนี้จะใช้ได้หากไฟล์มีช่องว่างในชื่อ


3

วิธีการที่ไม่ใช่ขั้ว

extract hereเพียงแค่เลือกไฟล์ซิปให้คลิกขวาที่หนึ่งและเลือก คุณสามารถเลือกไฟล์ซิปทั้งหมดหรือเพียงบางไฟล์ในเวลาเดียวกัน


1

unzip \*.zip หรือ unzip '*.zip'

ชัดเจนunzip *.zipไม่ทำงานเพราะเปลือกขยายไปunzip foo.zip bar.zip ...และunzipตีความชื่อไฟล์แรกเป็นไฟล์ซิปและชื่อไฟล์ต่อไปนี้เป็นไฟล์ที่จะแยกจากไฟล์ซิปที่

อย่างไรก็ตามunzipเป็นเรื่องแปลกในหมู่คำสั่งของ Unix ที่มันทำหน้าที่ขยายตัวเอง หาก*ไม่ได้ขยายโดยเชลล์ให้ unzip ทำและแทรกชื่อไฟล์ที่ได้ทั้งหมดเป็นไฟล์ซิปที่ต้องดำเนินการ ดังนั้นในกรณีพิเศษนี้ใคร ๆ ก็สามารถหนีไปได้โดยไม่มีforลูปหรืออะไรxargsทำนองนั้น

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