Tăng tất cả các tệp PDF trong một thư mục, giữ lại cấu trúc thư mục


11

Tôi đang cố gắng tạo một tarball nén chứa tất cả các tệp PDF tồn tại trong một trong các thư mục của tôi. Cấu trúc thư mục cần được giữ lại. Thư mục trống không cần thiết, nhưng tôi thực sự không quan tâm nếu chúng ở đó.

Ví dụ: giả sử tôi có một thư mục trông như thế này:

dir
dir/subdir1
dir/subdir1/subsubdir1/song.mp3
dir/subdir2
dir/subdir2/subsubdir1
dir/subdir2/subsubdir1/document.pdf
dir/subdir2/subsubdir1/another-song.mp3
dir/subdir2/subsubdir1/top-ten-movies.txt
dir/subdir3
dir/subdir3/another-document.pdf

Sau khi chạy lệnh, tôi muốn có dir.tar.gzchứa điều này:

dir
dir/subdir2
dir/subdir2/subsubdir1
dir/subdir2/subsubdir1/document.pdf
dir/subdir3
dir/subdir3/another-document.pdf

Khả thi?

Câu trả lời:


10

Điều này sẽ liệt kê tất cả các tệp PDF:

$ find dir/ -name '*.pdf'
./dir/subdir2/subsubdir1/document.pdf
./dir/subdir3/another-document.pdf

Bạn có thể đặt đường dẫn đó để xargslấy nó thành một dòng được phân tách bằng dấu cách và cung cấp dữ liệu đó tarđể tạo tệp lưu trữ:

$ find dir/ -name '*.pdf' | xargs tar czf dir.tar.gz

(Cách này bỏ qua các thư mục trống)


1
Điều đó thật tuyệt vời, cảm ơn vì sự giúp đỡ. Đây là những gì tôi nghĩ ra:find docs \( -iname '*.pdf' -o -iname '*.mp3' \) -printf '"%p"\n' | xargs tar czf docs-media.tar.gz
Matt Alexander

3
@mattalexx: Coi chừng lệnh này sẽ không hoạt động nếu bất kỳ tên tệp nào chứa dấu cách hoặc \'"(lỗi của xargs) và sẽ không hoạt động nếu có quá nhiều tên tệp (lỗi của kernel).
Gilles 'SO- ngừng trở nên xấu xa'

2
@Gilles Liên quan đến tên tập tin có dấu cách và dấu ngoặc đơn, -printf '"%p"\n'phần này quan tâm đến điều đó (ít nhất là nó đã làm cho tôi).
Matt Alexander

1
@Gilles Thú vị về hạn chế kernel. Bạn có thể có bao nhiêu đối số trong một lệnh trong Linux?
Matt Alexander

5
Ồ, trên mạng sẽ không hoạt động, hãy lưu ý rằng chế độ thất bại ở đây là nếu dòng lệnh quá dài, xargs sẽ phân tách nó, do đó, lệnh gọi tar cuối cùng sẽ âm thầm ghi đè lên các tệp được viết bởi các lệnh trước đó .
Gilles 'SO- ngừng trở nên xấu xa'

6

Với bash 4 hoặc zsh và GNU tar:

tar -czf dir.tar.gz dir/**/*.pdf

Điều này có thể không hoạt động nếu bạn có số lượng tệp PDF rất lớn và dòng lệnh quá dài. Sau đó, bạn sẽ cần một giải pháp dựa trên tìm kiếm phức tạp hơn (một lần nữa, sử dụng GNU tar):

tar -cf dir.tar -T /dev/null
find dir -name '*.pdf' -exec tar -rf dir.tar {} +
gzip dir.tar

Ngoài ra (và có thể) bạn có thể tạo kho lưu trữ với pax .

pax -w -x ustar -s '/\.pdf$/&/' -s '/.*//' . | gzip >dir.tar.gz

Đầu tiên -snói bao gồm tất cả .pdfcác tập tin, mà không thay đổi tên của họ. Thứ hai -snói đổi tên tất cả các tệp khác thành một tên trống, điều này thực sự có nghĩa là không đưa chúng vào kho lưu trữ.


Ồ vâng, tôi muốn nói đến zsh's **; Tôi thậm chí còn không nhận ra bash 4 đã có ngay bây giờ
Michael Mrozek
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.