Làm cách nào để nén nhiều tệp trên dòng lệnh?


16

Tha thứ cho câu hỏi cơ bản nhất này, nhưng tôi không thể tìm thấy câu trả lời trực tiếp hoặc ví dụ đơn giản về trao đổi ngăn xếp.

Giả sử tôi có một thư mục tệp mà tôi muốn nén thành một tệp zip mà tôi có thể chia sẻ với những người bạn Windows khủng khiếp của mình (nếu không tôi chỉ sử dụng tarvà hoàn thành nó). Nó trông như thế này:

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

Giả sử tôi đã zipcài đặt:

sudo apt-get install zip

Tôi thấy từ man zipđó cho phép tôi sử dụng một danh sách tập tin:

- @ danh sách tập tin. Nếu danh sách tệp được chỉ định là - @ [Không có trên MacOS], zip sẽ lấy danh sách các tệp đầu vào từ đầu vào tiêu chuẩn thay vì từ dòng lệnh. Ví dụ,

          zip -@ foo

Vì vậy, tôi đã tạo ra zip.lsttrông như thế này:

cat zip.lst

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

Và bây giờ tôi đã thử:

zip -@ zip.lst

Nhưng nó không làm gì cả, ngoại trừ tạo một dòng trống trên bàn điều khiển. Và tôi có thể tiếp tục đẩy Entervà nó chỉ tiếp tục tạo ra nhiều dòng trống hơn mà dường như không thực thi lệnh. Sau một số tìm kiếm, tôi nhận ra rằng tôi cần phải chấm dứt đầu vào bằng cách nhấn Ctrl+D

Nhưng bây giờ tôi gặp lỗi này:

    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)

Gì!? Làm thế nào là danh sách đơn giản của tôi không phải là một "cấu trúc tệp hợp lệ"? Quay lại hướng dẫn để biết thêm thông tin và tôi xem kỹ hơn:

Nếu danh sách tệp được chỉ định là - @ ...

Vì vậy, tôi đã thử nó mà không có -@, và ít nhất là xử lý nó ngay lập tức mà không cần phải nhấn Ctrl+ Dnhưng tôi vẫn để lại lỗi tương tự .

May mắn thay, tôi tìm thấy một nhận xét về một câu trả lời cho một câu hỏi gần như không liên quan khiến tôi nhận ra rằng tôi cần phải đặt tên rõ ràng cho tệp zip. Lỗi này là do mặc định nó đang cố tạo một tệp zip có tên zip.lst. Nhưng vì đó là tên của danh sách của tôi, người ta có thể nghĩ rằng nó chỉ đơn giản sẽ ghi đè lên nó, nhưng không, thực tế nó đang cố gắng cập nhật nó. Và vì danh sách rõ ràng không phải là tệp zip, chúng tôi gặp lỗi cấu trúc tệp không hợp lệ và bây giờ thì rõ ràng lý do tại sao nó nói "có thể không phải là tệp zip." Vì vậy, sau đó tôi đã cố gắng:

zip files.zip zip.lst

adding: zip.lst (deflated 35%)

Eureka! Tôi có thể thấy tệp zip đã được tạo và thư mục của tôi hiện chứa tệp này:

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

Nhưng hãy đợi trước khi chúng tôi ăn mừng, hãy xác nhận nội dung của tệp zip trước:

unzip -l files.zip

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

Không! Chà, thực sự điều đó có ý nghĩa từ việc sử dụng tiêu chuẩn bởi vì nó chỉ nén một tệp danh sách mà tôi đã cung cấp. Cuối cùng tôi đã thử lại -@nhưng nhận được kết quả tương tự.

Tôi đang làm gì sai?

BTW, tôi biết tôi có thể sử dụng GUI và thực hiện bằng chuột, nhưng tôi cần phải viết kịch bản này và nói chung tôi sẽ nhanh hơn trên CLI khi tôi biết tôi đang làm gì.

Câu trả lời:


23

Sử dụng <chuyển hướng tập tin

zip files.zip -@ < zip.lst

Hoặc bạn có thể bỏ qua danh sách và chỉ toàn cầu

zip files.zip *.txt *.jpg

cảm ơn thép

Câu trả lời lịch sử

Tôi rất vui khi trả lời câu hỏi của mình vì tôi muốn ghi lại sự hỗn loạn của mình với hy vọng rằng những người khác theo sau những giọt nước mắt của tôi có thể được tha thứ bằng cách tìm kiếm một số từ khóa.

Cuối cùng, tôi phát hiện ra câu trả lời đúng , nhưng nó đã được đăng vào câu hỏi sai .

Một vài điểm rõ ràng:

  • Hướng dẫn không đề cập đến một danh sách bằng chữ như trong một tệp, mà đúng hơn là liệt kê các tệp ra trên bàn điều khiển.
  • Có thể hiểu rằng ai đó có thể bị nhầm lẫn khi nghĩ foođến danh sách tệp, nhưng thực ra nó có ý định đại diện cho tên của tệp zip đầu ra.
  • Danh sách các tệp bị bỏ qua trong ví dụ vì nó sử dụng -@khóa chuyển, điều này chứng tỏ nó "lấy danh sách các tệp đầu vào từ đầu vào tiêu chuẩn thay vì từ dòng lệnh "

Hiểu được điều này, chúng tôi hiện được trang bị nhiều cách khác nhau để hoàn thành mục tiêu.

Trước tiên, sử dụng danh sách tệp mà chúng tôi đã tạo, chúng tôi có thể đọc danh sách đó catvà chuyển hướng đầu ra với một đường ống làm đầu vào tiêu chuẩn sang 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%)

Thấy rằng adding: ...đối với mỗi tệp chắc chắn là một dấu hiệu tốt, nhưng chúng tôi đã hy vọng trước đó, vì vậy hãy xác nhận:

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

NGỌT! Nhưng ai muốn tạo một danh sách sử dụng một lần nào? Đó là một cách tuyệt vời để giải quyết tình huống đặc biệt này. Sẽ là tốt hơn để có được một danh sách từ lsvà ống dẫn đến zip:

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%)

Tuyệt vời! Bây giờ, hãy tạo các bộ lọc với sức mạnh tuyệt vời grepđể chỉ nén các jpg chẳng hạn:

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

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

Hoặc chỉ các tệp bắt đầu bằng "tệp"

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
Thay vì sử dụng lsgrepvà zip -@, bạn có thể sử dụng các khối vỏ để chọn tệp trực tiếp trên dòng lệnh zip, vd zip files.zip file*hoặc zip images.zip *.jpg. Ngoài ra, khi sử dụng danh sách tên tệp từ một tệp, bạn có thể sử dụng chuyển hướng thay vì gọi một quy trình riêng cho mèo,zip files.zip -@ < zip.lst
Steeldo

Làm thế nào bạn có thể làm cho điều này làm việc với các thư mục lồng nhau cùng với các tập tin?
BallpointBen

@BallpointBen tôi sẽ sử dụng findthay vìls
Jeff Puckett

6

lệnh đơn giản nhất với mức nén tối đa

zip -9 -r filename.zip /path/to/dir singlefile.jpg 
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.