Zip tất cả các tập tin trong thư mục?


483

Có cách nào để nén tất cả các tệp trong một thư mục đã cho bằng ziplệnh không? Tôi đã nghe nói về việc sử dụng *.*, nhưng tôi cũng muốn nó hoạt động cho các tệp không có phần mở rộng.


2
Bạn đã thử điều hướng lên một cấp từ thư mục mong muốn của bạn và làm zip myarch.zip mydir/*chưa?
Joseph R.

13
hoặc tốt hơnzip -r myarch.zip mydir/*
Adam

25
hoặc tốt hơnzip -r myarch.zip mydir
ctrl-alt-delor

*.*có nghĩa là bất kỳ tập tin với một dấu chấm. Trong cp / m và dos, tất cả các tệp đều có dấu chấm và nó khiến bạn nhập nó (không thể làm được *). Do đó mọi người đến xem *.*như tất cả các tập tin. Cuối cùng, Microsoft đã thêm các tên tệp dài có thể có 0 hoặc nhiều dấu chấm. Để tìm một tập tin có dấu chấm trên windows, bạn phải gõ *.*.*.
ctrl-alt-delor

Câu trả lời:


705

Bạn chỉ có thể sử dụng *; không có nhu cầu *.*. Phần mở rộng tệp không phải là đặc biệt trên Unix. *phù hợp với không hoặc nhiều ký tự khác bao gồm một dấu chấm. Vì vậy, nó phù hợp foo.png, bởi vì đó là 0 hoặc nhiều ký tự (chính xác là bảy).

Lưu ý rằng *theo mặc định không khớp các tệp bắt đầu bằng dấu chấm (không có dấu chấm *.*). Đây thường là những gì bạn muốn. Nếu không, trong bash, nếu bạn shopt -s dotglobsẽ (nhưng vẫn sẽ loại trừ ...). Các shell khác có các cách khác nhau (hoặc không có gì cả) bao gồm các dotfiles.

Ngoài ra, zipcũng có một -rtùy chọn (đệ quy) để thực hiện toàn bộ cây thư mục cùng một lúc (và không phải lo lắng về vấn đề dotfile):

zip -r myfiles.zip mydir

nơi mydirlà thư mục chứa tập tin của bạn. Lưu ý rằng zip được sản xuất sẽ chứa cấu trúc thư mục cũng như các tệp. Như peterph chỉ ra trong nhận xét của mình, điều này thường được xem là một điều tốt: trích xuất zip sẽ lưu trữ gọn gàng tất cả các tệp được trích xuất trong một thư mục con.

Bạn cũng có thể yêu cầu zip không lưu trữ các đường dẫn với tùy chọn -j/ --junk-paths.

Các ziplệnh đi kèm với tài liệu hướng dẫn nói cho bạn về tất cả (nhiều) tùy chọn của nó; gõ man zipđể xem tài liệu đó. Đây không phải là duy nhất cho zip; bạn có thể lấy tài liệu cho hầu hết các lệnh theo cách này.


9
Bạn có thể muốn thêm, rằng nó được coi là một cách thực hành tốt để chứa mọi thứ trong kho lưu trữ trong một thư mục cấp cao nhất - để người ta không làm ô nhiễm thư mục hiện tại của mình khi trích xuất.
peterph

@peterph xong. Mặc dù đây không phải là quy ước trong các tệp zip so với ví dụ, tarfiles, tôi sợ.
derobert

không may là đúng vậy. Có lẽ là do di sản windows của drag'n'drop với di sản máy tính để bàn và linux làm việc với mã nguồn.
peterph

2
Hãy nhớ rằng *shell-continbing không bao gồm dotfiles (ví dụ: tên tệp bắt đầu bằng .). Đây là một lợi thế khác để nén toàn bộ thư mục theo tên.
mrb

Nhưng sử dụng -r bao gồm chính thư mục, nó phá vỡ những gì tôi đang làm. Sẽ không * bao gồm ...?
tkbx

11

Trong trường hợp của tôi, tôi muốn nén từng tệp vào kho lưu trữ của riêng mình, vì vậy tôi đã làm như sau (trong zsh):

$ for file in *; do zip ${file%.*}.zip $file; done

1
Không có mkvở đây à? Ngoài ra không có gì ở đây là đặc biệt zsh. Bạn sẽ muốn trích dẫn chính xác bất kỳ biến nào có chứa tên tệp, do đó, zip "${file%.*}.zip" "$file"với dấu ngoặc kép xung quanh cả hai biến.
tripleee

1
@tripleee Trước tiên, cảm ơn bạn đã chỉ ra tài liệu tham khảo sai lầm của tôi mkv. Thứ hai, trích dẫn đối số là không cần thiết zsh, không giống như trong bash. Đó là lý do tại sao tôi xác định rằng đây là một lệnh cho zsh.
Radon Rosborough

Thay thế dấu chấm phẩy cuối cùng bằng ký hiệu và có thể tăng tốc đáng kể (Nếu số lượng tệp trong thư mục là hợp lý ...). Mặt khác find . -type f -maxdepth 1 -print0|xargs -r0 -n1 -P64 -I{} bash -c 'f="{}"; zip "${f%.*}.zip" "$f"'(với -Pđiều chỉnh tùy thuộc vào luồng CPU của bạn ...) (Nhiều phụ thuộc GNU ...)
Gert van den Berg

5

Một cách khác là sử dụng find và xargs: (điều này có thể bao gồm thư mục "." Trong zip, nhưng nó vẫn sẽ giải nén chính xác. Với thử nghiệm của tôi, zip đã tước dấu chấm trước khi nén) find . -type f -exec zip zipfile.zip {} +

(Có +thể thay thế bằng \;nếu phiên bản của findbạn không hỗ trợ +kết thúc cho exec. Mặc dù vậy, nó sẽ chậm hơn ...)

Điều này theo mặc định sẽ bao gồm tất cả các thư mục phụ. Trên GNU find -maxdepthcó thể ngăn chặn điều đó.


(không giống như các giải pháp sử dụng *, điều này sẽ bao gồm các dotfiles và sẽ không bị đổ nếu có quá nhiều tệp trong một thư mục)
Gert van den Berg

1

Một phương thức (chậm) khác để thực hiện việc này (thêm một tệp vào zip mỗi lần):

for f in * .[^.]*; do
    [ -r "$f" ] || continue # Skip directories or non-existant files (Probably ".[^.]*" if directory has no dotfiles). Using -e will allow directories to be used as well
    zip zipfile.zip "$f" # If directories are included, you probably want to add -r
done

Điều này có các vấn đề về dotfile *(đã thêm cách giải quyết) và sẽ được bắt đầu zip một lần cho mỗi tệp, thêm nó vào kho lưu trữ. Trong bashđó, nó sẽ đối phó với một lượng lớn các tập tin.

Nó sẽ chậm hơn hầu hết các phương pháp khác, nhưng tương đối đơn giản.


1
Tôi sẽ nói rằng điều này ít đơn giản hơn câu trả lời được chấp nhận và chậm hơn, điều này đặt ra câu hỏi: "Tại sao mọi người sẽ làm điều này?". Nếu bạn có thể trả lời câu hỏi đó, tôi khuyên bạn nên đặt bối cảnh đó vào câu trả lời của mình, nếu không tôi nghĩ đó là một câu trả lời tồi cho một câu hỏi cũ đã có câu trả lời hay.
Centimane

@Centimane: Tôi lưu ý những hạn chế. Tôi cảm thấy điều này có giá trị giáo dục. (Nếu không bỏ qua các thư mục, nó khá đơn giản). Thay vào đó, nếu bạn muốn có câu trả lời nhanh hơn bằng cách sử dụng một công cụ bên ngoài (tiêu chuẩn), thì câu trả lời khác của tôi sẽ bao gồm điều đó. (với việc xử lý dotfiles bị xóa (ảnh hưởng đến tính chính xác mà không có sự vắng mặt được đề cập trong câu hỏi), tôi cảm thấy nó khá thanh lịch):for f in *; do zip zip.zip "$f"; done
Gert van den Berg

1
Lưu ý rằng câu trả lời được chấp nhận không sử dụng lệnh bên ngoài và sẽ nhanh hơn. Trong kịch bản nào câu trả lời này sẽ hữu ích?
Centimane

@Centimane Với tar khi có nhiều tệp hơn những gì bash có thể truyền dưới dạng tham số. (tìm + xargs là tốt hơn, cho các vòng lặp dễ dàng hơn ...). Đó là một câu trả lời (duy nhất) cho câu hỏi. Nó chắc chắn không phải là câu trả lời tối ưu. (Câu trả lời không tối ưu vẫn có thể hữu ích cho các vấn đề tương tự, nếu ai đó có tình huống hơi khác - ví dụ: muốn tập tin tar bất kỳ thư mục nào trong đó)
Gert van den Berg
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.