giải nén hàng loạt tập tin gzip mà không cần mở rộng gz


7

Tôi có một số lượng lớn các tệp có phần mở rộng như .0_1234 .0_4213.0_4132vv Một số trong số này được gzipnén và một số là email thô. Tôi cần xác định đó là các tệp nén, giải nén chúng và đổi tên tất cả các tệp thành một phần mở rộng chung sau khi tất cả các tệp nén được giải nén. Tôi đã tìm thấy tôi có thể sử dụng lệnh tệp để xác định tệp nào được nén, sau đó grep kết quả và sử dụng sedđể thu nhỏ đầu ra xuống danh sách các tệp, nhưng không thể xác định cách giải nén các phần mở rộng dường như ngẫu nhiên. Đây là những gì tôi có cho đến nay

file *|grep gzip| sed -e 's/: .*$//g'

Tôi muốn sử dụng xargshoặc một cái gì đó để lấy danh sách các tệp được cung cấp ở đầu ra và đổi tên chúng thành .gzđể chúng có thể được giải nén hoặc đơn giản là giải nén chúng theo dòng.


Hoặc di chuyển các tệp được nén vào thư mục mới / temp hoặc đặt đầu ra của danh sách vào một tệp. Nếu bạn biết các tệp chỉ là văn bản được nén, thì bạn có thể chỉ cần lặp qua danh sách và chuyển chúng sang một tệp mới. Không chắc cách thức hoạt động với dữ liệu nhị phân ...
ivanivan

Câu trả lời:


5

Không sử dụng gzip, sử dụng zcatthay vào đó không mong đợi một phần mở rộng. Bạn có thể làm tất cả mọi thứ trong một lần. Chỉ cần thử zcattệp và nếu thất bại vì nó không được nén, catthay vào đó:

for f in *; do 
    ( zcat "$f" || cat "$f" ) > temp && 
    mv temp "$f".ext && 
    rm "$f" 
done

Tập lệnh ở trên trước tiên sẽ thử zcattập tin vào tempvà nếu thất bại (nếu tập tin không ở định dạng gzip), nó sẽ chỉ catnhư vậy. Điều này được chạy trong một lớp con để nắm bắt đầu ra của bất kỳ lệnh nào chạy và chuyển hướng nó đến một tệp tạm thời ( temp). Sau đó, temptên được đổi thành tên tệp gốc cộng với một phần mở rộng ( .exttrong ví dụ này) và bản gốc bị xóa.


Ngoài ra, bạn có thể muốn kiểm tra lỗi về "$f".extđã tồn tại. Hoặc sử dụng mv -i.
derobert

@don_crissti Tôi biết zcatsử dụng gzipnhưng trên hệ thống của tôi, ít nhất, tôi không thể gzipchấp nhận các tệp mà không có .gztiện ích mở rộng và điều này xoay quanh vấn đề đó. Làm thế nào tôi sẽ làm điều đó trong một lần?
terdon

@derobert đúng, mặc dù tôi cho rằng OP sẽ không có tiền vì họ muốn đổi tên tự động.
terdon

1
@don_crissti Argh! Không tôi đã không và tôi đã bỏ lỡ chi tiết thiết yếu mà bạn đang gửi đầu ra đến thiết bị xuất chuẩn. Vâng, thực sự, đó là một cách tiếp cận tốt hơn nhiều. Tại sao bạn không đăng nó như một câu trả lời?
terdon

2
Một sự khác biệt giữa điều này và gọi gunzipgunzipbảo tồn thời gian sửa đổi.
Gilles 'SO- ngừng trở nên xấu xa'

4

Bạn có thể làm một cái gì đó như

for f in ./*
do 
gzip -cdfq "$f" > "${f}".some_ext
done

Điều này xử lý tất cả các tệp (ngay cả những tệp không nén, thông qua -f) và ghi (thông qua -c) đầu ra vào thiết bị xuất chuẩn bằng cách sử dụng chuyển hướng để lưu nội dung của từng tệp vào .some_extđối tác của nó . Sau đó, bạn có thể xóa bản gốc, ví dụ như vớibash

shopt extglob
rm -f ./!(*.some_ext)

hoặc là zsh

setopt extendedglob
rm -f ./^*some_ext

Bạn thậm chí có thể lưu các tệp kết quả vào một thư mục khác (lần này giả sử bạn muốn xóa tiện ích mở rộng ban đầu), vd

for f in *
do 
gzip -cdfq -- "$f" > /some/place/else/"${f%.*}".some_ext
done

và sau đó loại bỏ mọi thứ trong thư mục hiện tại ...


Giống như câu trả lời của Terdon, điều này không tránh việc sao chép các tệp không nén. Nhưng nếu bạn không quan tâm đến điều đó, -ftùy chọn của gzip để chuyển qua dữ liệu không được nén không thay đổi là cách tốt nhất, vì vậy +1.
Peter Cordes

3

Điều này sẽ trình bày một danh sách tất cả các tệp được nén bằng gzip:

file /path/to/files | grep ': gzip compressed data' | cut -d: -f1

Để giải quyết một .gzphần mở rộng trên bất kỳ tệp được nén nào, bản hack xấu xí này có thể thực hiện:

for file in ./*; do
    if gzip -l "$file" > /dev/null 2>&1; then
        case "$file" in
          *.gz) :;; # The file already has the extension corresponding to its format
          *) mv "$file" "${file}.gz";;
        esac
        # Uncomment the following line to decompress them at the same time
        # gunzip "${file}.gz"
    fi
done
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.