Chuyển đổi tập tin gzip thành bzip2 hiệu quả


10

Tôi có một loạt các tệp gzip mà tôi phải chuyển đổi sang bzip2 mỗi giờ. Hiện tại, tôi đang sử dụng tập lệnh shell chỉ đơn giản là 'gunzip' cho mỗi tệp và sau đó là 'bzip2'. Mặc dù điều này hoạt động, nó mất rất nhiều thời gian để hoàn thành.

Có thể làm cho quá trình này hiệu quả hơn? Tôi đã sẵn sàng để lặn và xem xét mã nguồn của gunzip và bzip2 nếu cần thiết, nhưng tôi chỉ muốn chắc chắn về khoản thanh toán. Có bất kỳ hy vọng để cải thiện hiệu quả của quá trình?

Câu trả lời:


1

Câu hỏi này đã được hỏi từ lâu khi pbzip2 không có sẵn hoặc không có khả năng nén từ stdin, nhưng bây giờ bạn có thể song song cả hai bước giải nén và nén bằng cách sử dụng song songpbzip2 (thay vì bzip2 ):

ls *.gz | parallel "gunzip -c {} | pbzip2 -c > {.}.bz2"

nhanh hơn đáng kể so với sử dụng bzip2 .


Xin chào, tôi đã thay đổi câu trả lời được chấp nhận cho câu hỏi này vì điều này mang lại lựa chọn tốt nhất cho những người vấp phải câu hỏi ngày hôm nay. Cảm ơn đã pbzip2đề cập. Trong trường hợp liên kết không tải cho bất kỳ ai khác, đây là trang dự ántrang man .
Sundar

15

Thay vì gunzip trong một bước và bzip2 ở bước khác, tôi tự hỏi liệu có lẽ sẽ hiệu quả hơn khi sử dụng đường ống. Cái gì đó nhưgunzip --to-stdout foo.gz | bzip2 > foo.bz2

Tôi đang suy nghĩ với hai hoặc nhiều CPU, điều này chắc chắn sẽ nhanh hơn. Nhưng có lẽ ngay cả với chỉ một lõi. Mặc dù vậy, tôi xấu hổ thừa nhận đã không thử điều này.


2
+1 cho đường ống, I / O đĩa là điều bạn muốn tránh. Đối với nén, trừ khi tôi nhầm, bzip2 không tương đương. Bạn sẽ phải sử dụng một cái gì đó như pbzip2 để nén theo parallell: compression.ca/pbzip2
gustafc

... và thật không may, dường như không có tiện ích giải nén gzip parallell nào khả dụng.
gustafc

@gustafc: Cảm ơn bạn đã liên kết đến pbzip2, điều đó rất hữu ích ... @OP: Tôi tránh xa đường ống bcos Tôi muốn có thể xử lý các tệp gz bị hỏng, v.v., mà không mất chúng trong đường ống ...
Sundar

4
@gustafc: Ngay cả khi bzip2gzipkhông hoạt động song song trong nội bộ, bằng cách sử dụng một đường ống, bạn có thể khiến chúng hoạt động song song, bởi vì một đường ống ngầm bắt đầu hai quá trình, sẽ chạy song song. Vì vậy, ít nhất là giải nén và nén sẽ chạy song song.
sleske

1
@sleske, mặc dù bạn đúng về mặt lý thuyết, bzip2việc sử dụng CPU lùn hơn gunzipmột chút, vì vậy trong thực tế, sự song song bạn nhận được ở đây là tối thiểu. Không phải làm đĩa IO vẫn đẹp!
Johan Walles

6

GNU song song ( http://www.gnu.org/software/abul ) có thể là một tùy chọn nếu bạn có nhiều lõi (hoặc thậm chí nhiều máy):

ls *.gz | parallel "gunzip -c {} | bzip2 > {.}.bz2"

Đọc trang hướng dẫn / người đàn ông để biết chi tiết và các tùy chọn.


3

Những gì bạn đang làm là đặt cược tốt nhất của bạn. Không có công cụ chuyển đổi có sẵn và cố gắng bzip2 một tệp đã được nén đã không thực sự là một tùy chọn, vì nó thường có các hiệu ứng không mong muốn. Vì thuật toán là khác nhau, chuyển đổi sẽ liên quan đến việc lấy dữ liệu gốc bất kể. Tất nhiên trừ khi gzipping là một bước trong quy trình bzip2, trong đó không có gì đáng tiếc.


Không phải các thuật toán có bất kỳ bước chồng chéo nào để tôi có thể bỏ qua một bước trong giải nén gzip và tương tự trong nén bzip?
Sundar

2
@sundar Tôi sẽ không nghĩ như vậy. gzipsử dụng Leimpel-Ziv 77, trong khi bzip2sử dụng Burrows-Wheeler. Các thuật toán khác nhau, tôi sợ.
new123456

2

Thỉnh thoảng, tôi cần làm điều tương tự với các tệp nhật ký. Tôi bắt đầu với các tệp * .gz nhỏ nhất trước tiên ( ls -rS), gunzip và sau đó và bzip2 chúng riêng lẻ. Tôi không biết có thể chuyển trực tiếp đầu ra gunzip sang đầu vào bzip2 không. Lệnh bzip2 có tốc độ nén chậm hơn nhiều so với gunzip khi giải nén đến mức nó có thể tiêu tốn bộ nhớ và trao đổi không gian trên máy chủ.

Cải tiến hoặc đề xuất đều được chào đón. Đây là một lót của tôi:

for i in $(ls -rS *.gz | sed 's/\.gz//'); do gunzip ${i}.gz; bzip2 -9 ${i}; done

Cảm ơn đầu vào, điểm về sự khác biệt về tốc độ giữa hai quá trình và ý nghĩa của nó là một điều quan trọng.
Sundar


1

Chỉ cần làm điều này một vài phút trước đây:

find . -name "*.gz" | perl -pi -e 's/\.gz$//g;' | xargs -n1 ./rezip

Trường hợp rezipsẽ được định nghĩa là:

#!/bin/bash
gunzip -v $1.gz && bzip2 -9v $1

Tùy chọn, bạn cũng có thể làm cho nó đa luồng bằng cách sử dụng một -Ptùy chọn với xargs, nhưng hãy cẩn thận với tùy chọn đó. (Bắt đầu thấp!)

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.