Kết nối nhanh nhiều tệp GZip


92

Tôi có danh sách các tệp gzip:

file1.gz
file2.gz
file3.gz

Có cách nào để nối hoặc nén các tệp này thành một tệp gzip mà không cần phải giải nén chúng không?

Trong thực tế, chúng tôi sẽ sử dụng điều này trong cơ sở dữ liệu web (CGI). Nơi web sẽ nhận một truy vấn từ người dùng và liệt kê tất cả các tệp dựa trên truy vấn và trình bày chúng trong một tệp hàng loạt trở lại người dùng.

Câu trả lời:


107

Với các tệp gzip, bạn có thể chỉ cần nối các tệp với nhau, như sau:

cat file1.gz file2.gz file3.gz > allfiles.gz

Theo gzip RFC ,

Một tệp gzip bao gồm một loạt các "thành viên" (tập dữ liệu nén). [...] Các thành viên chỉ xuất hiện lần lượt trong tệp, không có thông tin bổ sung trước, giữa hoặc sau họ.

Lưu ý rằng điều này không hoàn toàn giống với việc xây dựng một tệp gzip của dữ liệu được nối; trong số những thứ khác, tất cả các tên tệp gốc được giữ nguyên. Tuy nhiên, gunzip dường như xử lý nó tương đương với một nối.

Vì các công cụ hiện có thường bỏ qua tiêu đề tên tệp cho các thành viên bổ sung, nên không dễ dàng trích xuất các tệp riêng lẻ từ kết quả. Nếu bạn muốn điều này thành có thể, hãy tạo một tệp ZIP. ZIP và GZIP đều sử dụng thuật toán DEFLATE để nén thực tế (ZIP hỗ trợ một số thuật toán nén khác cũng như một tùy chọn - phương pháp 8 là phương pháp tương ứng với nén của GZIP); sự khác biệt là ở định dạng siêu dữ liệu. Vì siêu dữ liệu không được nén nên nó đủ đơn giản để loại bỏ các tiêu đề gzip và giải quyết các tiêu đề tệp ZIP và bản ghi thư mục trung tâm để thay thế. Tham khảo thông số kỹ thuật định dạng gzipthông số kỹ thuật định dạng ZIP .


41
Không. Chỉ là cat file1.gz file2.gz file3.gz > allfiles.gz. Nó thực sự là đơn giản :)
bdonlan

1
về mặt kỹ thuật mà nói, chúng được bảo tồn. Chỉ là các công cụ hiện có thường không có khả năng trích xuất chúng một cách riêng biệt. Bạn có thể muốn xem xét việc xây dựng tiêu đề và thư mục ZIP - định dạng ZIP sử dụng cùng một thuật toán nén cơ bản, vì vậy vấn đề chỉ là thay đổi siêu dữ liệu (không nén). Hãy xem gzip.org/zlib/rfc-gzip.html (định dạng nguồn) và pkware.com/documents/casestudies/APPNOTE.TXT .
bdonlan

20
Tốt hơn là xây dựng một zip các tệp gz, chỉ cần tar chúng. Nó giống như catcâu trả lời nhưng có thêm một số siêu dữ liệu. Sau đó, bạn có thể gỡ bỏ chúng để lấy tên tệp gốc, sau đó giải nén tất cả hoặc chỉ một vài tệp nếu cần.
sorpigal

1
nhiều nhận xét ở đây là về .zipcác tập tin. Cách tiêu chuẩn để gộp nhiều tệp lại với nhau thành một kho nén bằng thuật toán gzip (hoặc bzip2) là sử dụng tar: tarđặt các tệp lại với nhau (không nén) và giữ nguyên tên và thuộc tính tệp, công việc của gzip là nén kết quả. điều này thậm chí có thể được thực hiện trong một bước bằng cách sử dụng -ztùy chọn của tar. phần mở rộng tệp kết quả là .tar.gzhoặc .tgz. Trong trường hợp bạn muốn tập hợp các tệp .gz đã được nén lại với nhau, chỉ cần sử dụng tar. nó không thực hiện bất kỳ nén nào nữa, điều này có ý nghĩa đối với các tệp đã được nén.
Daniel Alder

2
@alvas, zcatgiải nén đầu vào của nó, vì vậy sẽ cung cấp cho bạn đầu ra được giải nén với .gzphần mở rộng.
bdonlan

51

Đây là những gì man 1 gzipnói về yêu cầu của bạn.

Nhiều tệp nén có thể được nối với nhau. Trong trường hợp này, gunzip sẽ trích xuất tất cả các thành viên cùng một lúc. Ví dụ:

gzip -c file1  > foo.gz
gzip -c file2 >> foo.gz

Sau đó

gunzip -c foo

tương đương với

cat file1 file2

Không cần phải nói, file1có thể được thay thế bằng file1.gz.

Bạn phải lưu ý điều này:

gunzip sẽ giải nén tất cả các thành viên cùng một lúc

Vì vậy, để có được tất cả các thành viên riêng lẻ, bạn sẽ phải sử dụng một cái gì đó bổ sung hoặc viết, nếu bạn muốn làm như vậy.

Tuy nhiên, điều này cũng được giải quyết trong trang người đàn ông.

Nếu bạn muốn tạo một tệp lưu trữ duy nhất với nhiều thành viên để các thành viên sau này có thể được trích xuất độc lập, hãy sử dụng trình lưu trữ như tar hoặc zip. GNU tar hỗ trợ -ztùy chọn gọi gzip một cách minh bạch. gzip được thiết kế như một bổ sung cho tar, không phải là một thay thế.


13

Chỉ sử dụng mèo. Nó rất nhanh (0,2 giây cho 500 MB đối với tôi)

cat *gz > final
mv final final.gz

Sau đó, bạn có thể đọc đầu ra bằng zcat để đảm bảo rằng nó đẹp:

zcat final.gz

Tôi đã thử câu trả lời khác của 'gz -c' nhưng tôi đã kết thúc với rác khi sử dụng các tệp đã được giải nén làm đầu vào (tôi đoán nó đã nén chúng gấp đôi).

PV:

Tốt hơn, nếu bạn có nó, hãy 'pv' thay vì mèo:

pv *gz > final
mv final final.gz

Điều này cung cấp cho bạn một thanh tiến trình khi nó hoạt động, nhưng thực hiện điều tương tự như mèo.


11

Bạn có thể tạo một tệp tar của các tệp này và sau đó gzip tệp tar để tạo tệp gzip mới

tar -cvf newcombined.tar file1.gz file2.gz file3.gz
gzip newcombined.tar

8
Chính xác tại sao bạn nên gzip tệp tar mới? Nó đã được nén (ngoài siêu dữ liệu của tar, phải nhỏ).
thiton

2
Bạn đúng rồi. Sẽ không có nhiều khác biệt về kích thước tệp cho dù bạn có gzip nó hay không vì các tệp riêng lẻ đã được nén. Đó chỉ là vì anh ta muốn có tệp gzip trong số ba tệp riêng lẻ.
Drona

1
Gzip bổ sung chỉ làm chậm việc truy cập vào nội dung mà không có lợi. Đối với tôi, dường như yêu cầu OP thực sự là tệp lưu trữ kết quả phải là một tệp duy nhất và không có lý do gì để cho rằng tệp kết quả phải là tệp gzip.
mc0e
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.