ฉันจะ zip หลายไฟล์ในบรรทัดคำสั่งได้อย่างไร


16

ยกโทษให้กับคำถามพื้นฐานที่สุด แต่ฉันไม่สามารถหาคำตอบโดยตรงหรือตัวอย่างง่ายๆในการแลกเปลี่ยนสแต็ค

สมมติว่าฉันมีโฟลเดอร์ของไฟล์ที่ฉันต้องการบีบอัดเป็นไฟล์ zip หนึ่งไฟล์ที่ฉันสามารถแบ่งปันกับเพื่อน Windows ที่น่ากลัวของฉันtarได้ ดูเหมือนว่านี้:

.
├── file1.txt
├── file2.txt
├── file3.txt
├── file.jpg
└── test.jpg

สมมติว่าฉันได้zipติดตั้ง:

sudo apt-get install zip

ฉันเห็นจากman zipที่อนุญาตให้ฉันใช้รายการไฟล์:

- รายชื่อไฟล์ @ หากระบุรายการไฟล์เป็น - @ [ไม่ใช่ใน MacOS] zip จะใช้รายการของไฟล์อินพุตจากอินพุตมาตรฐานแทนจากบรรทัดคำสั่ง ตัวอย่างเช่น,

          zip -@ foo

ดังนั้นฉันสร้างzip.lstที่มีลักษณะเช่นนี้:

cat zip.lst

file1.txt
file2.txt
file3.txt
file.jpg
test.jpg

และตอนนี้ฉันพยายาม:

zip -@ zip.lst

แต่มันไม่ได้ทำอะไรนอกจากสร้างบรรทัดว่างบนคอนโซล และฉันสามารถผลักEnterมันได้เรื่อย ๆ และมันก็แค่สร้างบรรทัดว่างขึ้นเรื่อย ๆ โดยไม่ต้องใช้คำสั่ง หลังจากการค้นหาบางอย่างฉันก็รู้ว่าฉันต้องยุติการป้อนข้อมูลด้วยการกดCtrl+D

แต่ตอนนี้ฉันได้รับข้อผิดพลาดนี้:

    zip warning: missing end signature--probably not a zip file (did you
    zip warning: remember to use binary mode when you transferred it?)
    zip warning: (if you are trying to read a damaged archive try -F)

zip error: Zip file structure invalid (zip.lst)

อะไร!? รายการแบบง่ายของฉันไม่ใช่ "โครงสร้างไฟล์ที่ถูกต้อง" อย่างไร กลับไปที่คู่มือสำหรับข้อมูลเพิ่มเติมและฉันลองดู:

หากระบุรายการไฟล์เป็น - @ ...

ดังนั้นผมจึงลองได้โดยไม่ต้อง-@และที่ไปที่กระบวนการอย่างน้อยได้ทันทีโดยไม่ต้องกดCtrl+ Dแต่ฉันทิ้งให้อยู่กับข้อผิดพลาดเดียวกัน

โชคดีที่ฉันพบความคิดเห็นเกี่ยวกับคำตอบของคำถามที่ไม่เกี่ยวข้องซึ่งทำให้ฉันรู้ว่าฉันต้องการตั้งชื่อไฟล์ zip อย่างชัดเจน error'd zip.lstนี้เพราะโดยค่าเริ่มต้นมันก็พยายามที่จะสร้างไฟล์ซิปที่เรียกว่า แต่เนื่องจากเป็นชื่อของรายการของฉันหนึ่งอาจคิดว่ามันจะเขียนทับมัน แต่ไม่ใช่ในความเป็นจริงพยายามอัปเดต และเนื่องจากรายการไม่ใช่ไฟล์ zip เราจึงได้รับข้อผิดพลาดของโครงสร้างไฟล์ที่ไม่ถูกต้องและตอนนี้ก็ชัดเจนว่าทำไมมันถึงพูดว่า "อาจไม่ใช่ไฟล์ zip" ดังนั้นฉันจึงลอง:

zip files.zip zip.lst

adding: zip.lst (deflated 35%)

ยูเรก้า! ฉันเห็นไฟล์ซิปถูกสร้างขึ้นและตอนนี้โฟลเดอร์ของฉันมีสิ่งนี้:

.
├── file1.txt
├── file2.txt
├── file3.txt
├── file.jpg
├── files.zip
├── test.jpg
└── zip.lst

แต่รอก่อนที่เราจะฉลองกันเถอะยืนยันเนื้อหาของไฟล์ zip ก่อน:

unzip -l files.zip

Archive:  files.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
       48  2016-05-24 15:30   zip.lst
---------                     -------
       48                     1 file

No! ที่จริงแล้วมันสมเหตุสมผลจากการใช้งานมาตรฐานเพราะมันแค่ซิปลิสต์ไฟล์เดียวที่ฉันให้ไว้ ในที่สุดฉันก็ลองอีกครั้ง-@แต่ได้ผลลัพธ์เหมือนกัน

ผมทำอะไรผิดหรือเปล่า?

BTW ฉันรู้ว่าฉันสามารถใช้ GUI และทำได้ด้วยเมาส์ของฉัน แต่ฉันต้องเขียนสคริปต์นี้และโดยทั่วไปฉันจะใช้ CLI เร็วขึ้นเมื่อฉันรู้ว่าฉันกำลังทำอะไรอยู่

คำตอบ:


23

ใช้การ<เปลี่ยนเส้นทางไฟล์

zip files.zip -@ < zip.lst

หรือคุณสามารถข้ามรายการและเพียงแค่หมุน

zip files.zip *.txt *.jpg

ขอบคุณผู้ขับเหล็ก

คำตอบทางประวัติศาสตร์

ฉันดีใจที่ไม่สามารถตอบคำถามของฉันเองได้เพราะฉันต้องการพงศาวดารความสับสนวุ่นวายด้วยความหวังว่าคนอื่น ๆ ที่ตามมาด้วยน้ำตาอาจจะรอดพ้นจากการค้นหาคำสำคัญ

ในที่สุดผมค้นพบคำตอบที่ถูกแต่มันก็โพสต์คำถามผิด

สองประเด็นที่ชัดเจน:

  • คู่มือไม่ได้อ้างถึงรายการตามตัวอักษรเหมือนกับในไฟล์ แต่เป็นการแสดงรายการไฟล์บนคอนโซล
  • เป็นที่เข้าใจได้ว่าบางคนอาจเข้าใจผิดคิดว่าfooอ้างถึงรายการไฟล์ แต่จริงๆแล้วตั้งใจจะแสดงชื่อของไฟล์ zip ที่ส่งออก
  • รายการของไฟล์ถูกละเว้นในตัวอย่างเนื่องจากใช้-@สวิตช์ซึ่งแสดงให้เห็นว่า "ใช้รายการของไฟล์อินพุตจากอินพุตมาตรฐานแทนจากบรรทัดคำสั่ง "

เมื่อทำความเข้าใจกับสิ่งนี้เรากำลังติดอาวุธด้วยวิธีที่หลากหลายเพื่อให้บรรลุเป้าหมาย

ก่อนอื่นใช้รายการไฟล์ที่เราสร้างขึ้นเราสามารถอ่านรายการด้วยcatและเปลี่ยนเส้นทางเอาต์พุตด้วยไพพ์เป็นอินพุตมาตรฐานไปยัง zip:

cat zip.lst | zip -@ files.zip

  adding: file1.txt (stored 0%)
  adding: file2.txt (stored 0%)
  adding: file3.txt (stored 0%)
  adding: file.jpg (stored 0%)
  adding: test.jpg (stored 0%)

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

unzip -l files.zip

Archive:  files.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  2016-05-24 14:54   file1.txt
        0  2016-05-24 14:54   file2.txt
        0  2016-05-24 14:54   file3.txt
        0  2016-05-24 15:00   file.jpg
        0  2016-05-24 14:59   test.jpg
---------                     -------
        0                     5 files

หวาน! แต่ใครที่ต้องการสร้างรายการใช้งานครั้งเดียวล่ะ นั่นเป็นวิธีการแก้ปัญหาที่น่ากลัวในรอบนี้ มันจะเป็นการดีกว่าถ้าคุณจะได้รายชื่อlsและไปป์ที่ซิป:

ls | zip -@ files.zip

  adding: file1.txt (stored 0%)
  adding: file2.txt (stored 0%)
  adding: file3.txt (stored 0%)
  adding: file.jpg (stored 0%)
  adding: test.jpg (stored 0%)

เหลือเชื่อ! ตอนนี้เรามาสร้างตัวกรองด้วยพลังอันยอดเยี่ยมของgrepการบีบอัดไฟล์ jpg เช่น:

ls | grep .jpg | zip -@ images.zip

  adding: file.jpg (stored 0%)
  adding: test.jpg (stored 0%)

หรือเพียงแค่ไฟล์ที่ขึ้นต้นด้วย "file"

ls | grep file. | zip -@ files.zip

  adding: file1.txt (stored 0%)
  adding: file2.txt (stored 0%)
  adding: file3.txt (stored 0%)
  adding: file.jpg (stored 0%)

5
แทนการใช้lsและgrepและไปรษณีย์ของ-@คุณสามารถใช้ globs เปลือกเพื่อเลือกไฟล์โดยตรงในบรรทัดคำสั่งเช่นซิปหรือzip files.zip file* zip images.zip *.jpgนอกจากนี้เมื่อใช้รายชื่อไฟล์จากไฟล์คุณสามารถใช้การเปลี่ยนเส้นทางแทนการเรียกกระบวนการแมวแยกต่างหากzip files.zip -@ < zip.lst
steeldriver

คุณจะทำให้มันทำงานกับไดเรกทอรีที่ซ้อนกันพร้อมกับไฟล์ได้อย่างไร?
BallpointBen

@BallpointBen ฉันจะใช้findแทนls
Jeff Puckett

6

คำสั่งที่ง่ายที่สุดที่มีระดับการบีบอัดสูงสุด

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