Tôi có một thư mục chứa khoảng 320116 tệp .pdb.gz. Tôi muốn giải nén tất cả. Nếu tôi sử dụng gunzip * .gz, nó sẽ báo lỗi, danh sách đối số quá dài. Thư mục có dung lượng khoảng 2GB. Xin vui lòng cho tôi một gợi ý thích hợp.
Tôi có một thư mục chứa khoảng 320116 tệp .pdb.gz. Tôi muốn giải nén tất cả. Nếu tôi sử dụng gunzip * .gz, nó sẽ báo lỗi, danh sách đối số quá dài. Thư mục có dung lượng khoảng 2GB. Xin vui lòng cho tôi một gợi ý thích hợp.
Câu trả lời:
find . -name '*.pdb.gz' -exec gunzip {} +
-exec gunzip {} +
sẽ cung cấp gunzip
nhiều nhưng không quá nhiều tên tệp trên dòng lệnh của nó. Điều này hiệu quả hơn so với -exec gunzip {} \;
việc bắt đầu một gunzip
quy trình mới cho mỗi và mọi tệp.
find
, ít hơn gunzip
!
find
cho phép ký hiệu "+". Xem, ví dụ, các find
trang người đàn ông cho BSD 10.1 . Cũng áp dụng cho OS X (ít nhất 10.9 trở lên, có thể sớm hơn).
Bất cứ khi nào bạn gặp lỗi "danh sách đối số quá dài", bạn có thể xử lý xung quanh nó bằng cách gọi lệnh mong muốn nhiều lần, mỗi lần với một tập hợp con các đối số bạn muốn sử dụng. xargs
là một công cụ giúp bạn làm điều đó tự động.
find . -type f -a -name \*.pdb.gz -print0 | xargs -0 gunzip
-execdir gunzip "{}" \;
tức là xargs sẽ gọi gunzip riêng cho từng tệp? Đó là cách đọc trang của tôi.
xargs
sẽ nhồi càng nhiều tên tệp sẽ phù hợp với gunzip
dòng lệnh. Thử nó! echo a b c d e f | xargs echo
chỉ gọi echo
một lần với tất cả 6 đối số để bạn thấy một dòng đầu ra (lệnh khá vô dụng để thực thi mặc dù !!!!) trong khi nếu bạn buộc xargs
chỉ cung cấp tối đa 3 đối số cho mỗi lần gọi lệnh echo a b c d e f | xargs -n 3 echo
thì bạn sẽ nhận được 2 dòng đầu ra .
xargs
là, với -P
tùy chọn, bạn có thể chạy gunzip
song song nhiều quy trình, điều này (tùy thuộc vào các tham số chính xác của hệ thống của bạn) có thể diễn ra nhanh hơn.
-P
, @psmears. Bây giờ tôi cũng đã học được điều gì đó!
Tôi nghĩ điều này sẽ hoạt động, nó chuyển đường dẫn / tên của từng tệp riêng lẻ sang gunzip để xử lý:
find /my/dir -name "*.pdb.gz" -execdir gunzip "{}" \;
find
với +
và xargs
được thiết kế rõ ràng với chính xác vấn đề đó trong tâm trí. Họ sẽ luôn cung cấp càng nhiều đối số càng tốt, trong khi không vượt quá giới hạn của hệ điều hành. Bởi vì, nhân tiện, nó là một giới hạn hệ điều hành, không có gì để làm với gunzip
.
Hãy thử cách này:
find . -name '*.gz' -exec gunzip {} \;
gunzip
một lần trên mỗi tệp. Xem câu trả lời của John1024 cho một cách hơi khác để tránh sự không hiệu quả.
Nếu bạn có một máy đa lõi, có lẽ bạn sẽ thấy rằng việc sử dụng gunzip
sẽ không phát huy tối đa khả năng của máy. Cho rằng bạn sẽ cần phải chạy nhiều gunzip
s song song. Để theo dõi những gì được thực hiện trong đó thiết bị đầu cuối bằng tay là cồng kềnh, nhưng bạn có thể dễ dàng làm điều đó với GNU song song:
find . -name "*.gz" | parallel -X gunzip {}
parallel
quá dài?
find
quá dài?
find
dòng lệnh của.
-name
Nó là không cần thiết để sử dụng find
cho việc này, vì bạn đã không đề cập đến các thư mục con. Những gì bạn cần làm là:
for f in *.gz;do gunzip $f;done
find
nếu bạn không muốn để đẻ trứng 320.116 gunzip
quá trình, giống như vòng lặp này không.