Làm cách nào để tìm tệp và tổng kích thước của chúng?


12

Tôi muốn tìm một loạt các tệp (dựa trên biểu thức ký tự đại diện) và tổng mức sử dụng đĩa của chúng.

Một cái gì đó như thế này:

$ find . -name 'flibble*' -ctime +90 -exec du -sh {} \;

2.1G    ./flibble_116.log
2.1G    ./flibble_83.log
2.1G    ./flibble_211040_157.log
2.1G    ./flibble3747_51.log

Công việc này. Nhưng nó không tạo ra kết quả mà tôi đang tìm kiếm. Nó liệt kê không gian được sử dụng bởi mỗi tệp, như findđang lặp qua chúng.

Những gì tôi muốn là tổng số ducho tất cả các tập tin được tìm thấy.

Câu trả lời:


12

Giải pháp

Bằng cách cung cấp tùy chọn -c(hoặc --total) cho du(1), bạn có thể hướng dẫn nó tạo ra tổng cộng lớn. Nếu việc triển khai du(1)hỗ trợ một trong hai tùy chọn này, bạn có thể đạt được hiệu quả mong muốn bằng cách sử dụng lệnh sau:

$ find . -name 'flibble*' -ctime +90 -exec du -shc {} +

EDIT: Lưu ý rằng nếu số lượng tệp vượt quá số lượng tham số tối đa được hệ thống của bạn cho phép, findvẫn có thể thực thi commandnhiều lần. Một số triển khai du(1)cũng hỗ trợ đọc tên tệp từ một tệp, không bị giới hạn đã đề cập:

$ find -name 'flibble*' -ctime +90 -print0 > filenames
$ du -shc --files0-from=filenames

Giải trình

Sự khác biệt giữa ngữ nghĩa của -exec command {} \;-exec command {} +là như sau:

  • command {} \;thực hiện commandmột lần cho mỗi kết quả của find. Tên đường dẫn của kết quả được thông qua thay vì {}.

    $ touch 1 2 3
    $ find  1 2 3 -maxdepth 0 -exec echo {} \;
    1
    2
    3
  • command {} +thực hiện command, khi tất cả các kết quả đã được lấy. Tên đường dẫn của kết quả được thông qua thay vì {}.

    $ touch 1 2 3
    $ find  1 2 3 -maxdepth 0 -exec echo {} +
    1 2 3

Các -print0tùy chọn nguyên nhân find(1)để in tên tập tin được tìm thấy đầu ra tiêu chuẩn phân cách bởi các ký tự null, và các --files0-fromtùy chọn gây ra du(1)để đọc các tên tập tin null-tách ra. Không giống như ký tự dòng mới, ký tự null có thể không xuất hiện trong tên tệp, do đó đầu ra không rõ ràng.

Để tìm hiểu thêm về các tùy chọn của du(1)find(1), bạn nên tham khảo các trang hướng dẫn tương ứng:

$ man du
$ man find

2
Bạn có thể kết thúc với nhiều tổng nếu số lượng tệp là quan trọng (1K +) do số lượng giới hạn đối số dòng lệnh.
ychaouche

Tôi có thể xác nhận @ychaouche, tôi gặp sự cố trong khi cố gắng đánh giá kích thước của hơn 30k tệp.
Adrien H

Nếu đó là một vấn đề, một số triển khai du(1)cũng hỗ trợ đọc tên tệp từ tệp : find 1 2 3 -maxdepth 0 -print0 > filenames; du -shc --files0-from=filenames.
Witiko

4

Thử cái này:

du -c `find . -name 'flibble*' -ctime +90` | tail -1

Lệnh ban đầu đưa ra một đối số du, sau đó thực thi nó, cho đến khi nó đi qua tất cả các đối số. Bằng cách này, bạn chỉ cần đưa ra tất cả các đối số cùng một lúc, sau đó cắt các kích thước riêng biệt và chỉ để lại tổng số. Bạn có thể xóa đường ống và đuôi để hiển thị kích thước của mỗi tệp nếu bạn muốn.


Điều này sẽ không tạo ra kết quả chính xác với tên đường dẫn chứa khoảng trắng. Cách đúng để làm điều này là sử dụng -exec du -c {} +tùy chọn find, sẽ chuyển các tên đường dẫn không thay đổi thành du.
Witiko

4

Bạn có thể thử điều này:

find . -name 'flibble*' -ctime +90 -exec du -ch {} + | grep total

2

Tôi sẽ findtự in ra kích thước và sử dụng một công cụ khác để tính tổng:

find . -name 'flibble*' -ctime +90 -printf "%s\n" |
perl -lnE '$sum += $_} END {say $sum'

Nếu bạn cũng muốn xem tên tập tin:

find . -name 'flibble*' -ctime +90 -printf "%s\t%p\n" |
perl -apE '$sum += $F[0]} END {say $sum'

1

Một lớp lót nên hoạt động để có tổng số Gigabyte trên hầu hết các hệ thống:

echo "$(( ($(find . -name 'flibble*' -ctime +90 -type f -printf '%k+' )0)/1024/1024 )) GB"
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.