Câu trả lời:
Bạn đang tìm đường ống ( |). Chúng là một cách kết nối nhiều lệnh và chuyển đầu ra của một lệnh làm đầu vào cho lệnh khác. Trong trường hợp này, bạn muốn chuyển tất cả các tên tệp bạn tìm thấy làm đầu vào du(tính toán kích thước). Tuy nhiên, do dutên hy vọng tập tin và kết quả findchỉ là một danh sách các văn bản (có, văn bản bao gồm tên tập tin, nhưng dukhông thể biết rằng, tất cả những gì nhìn thấy là văn bản), bạn cần phải sử dụng một cái gì đó như xargsđó sẽ mất mỗi dòng văn bản, coi nó như một tên tập tin và chuyển nó đến du. Đặt tất cả những thứ này lại với nhau, chúng ta có được:
find . -name "*.o" | xargs du -sch
bạn nên luôn luôn trích dẫn các mẫu bạn đưa ra find(như tôi đã làm ở trên "*.o":). Nếu bạn không, trình bao sẽ mở rộng *.otên của bất kỳ tệp phù hợp nào trong thư mục hiện tại. Nó chỉ hoạt động trong trường hợp này vì bạn không có tệp phù hợp.
Các -schcờ cho duđược ghi lại trong man du:
-c, --total
produce a grand total
-h, --human-readable
print sizes in human readable format (e.g., 1K 234M 2G)
-s, --summarize
display only a total for each argument
Lưu ý, tuy nhiên, điều này sẽ thất bại đối với tên tệp có chứa khoảng trắng. Điều này gần như chắc chắn sẽ không là vấn đề đối với các tệp đối tượng, nhưng trong tương lai, nếu bạn cũng cần xử lý các khoảng trắng, hãy sử dụng:
find . -name "*.o" -print0 | xargs -0 du -sch
Việc -print0tạo các dòng findin tách biệt NULL và -0tạo xargscác dòng như vậy làm đầu vào.
Ngoài ra, bạn có thể tự findin các kích thước và sau đó tổng hợp chúng:
find . -name "*.o" -printf '%s\n' | awk '{c+=$1}END{print c}'
Điều này cũng sẽ giải quyết vấn đề được đề cập bởi @Serg trong các bình luận có quá nhiều đối số và lệnh được chia thành các lệnh riêng biệt.
Nếu bạn đang sử dụng bash(có thể là bạn), có một cách đơn giản hơn:
shopt globstar
du -sch **/*.o
Các shopt globstarlàm cho lệnh **phù hợp với tất cả các file và thư mục con hoặc nhiều hơn. Sau khi kích hoạt nó, **/*.osẽ khớp với tất cả các tệp (và thư mục) có tên kết thúc .o, vì vậy chúng tôi có thể chuyển trực tiếp đến du.
Lưu ý rằng, không giống như findcách tiếp cận, điều này sẽ không khớp với các tệp ẩn (những tệp có tên bắt đầu bằng a .). Để phù hợp với những người là tốt, làm:
shopt -s dotglob globstar
du -sch **/*.o
Sử dụng -exec cờ để chạy dulệnh với ;(nghĩa là mỗi tệp)
find . -name "*.o" -exec du -b {} \; | awk '{total+=$1}END{print total}'
Đầu ra mẫu:
$ find . -name "*.txt" -exec du -b {} \; | awk '{total+=$1}END{print total,"bytes" }'
find: ‘./.cache/gvfs-burn’: Permission denied
find: ‘./.cache/unity’: Permission denied
852690242 bytes
findlà đệ quy - có nghĩa là nó đi qua tất cả các thư mục con. Nếu bạn chỉ muốn lấy tổng số tất cả *.ocác tệp trong thư mục hiện tại, chỉ cần làm
du -b -c *.o
với perl:
perl -le 'map { $sum += -s } @ARGV; print $sum' -- *.pdf
Kích thước của tất cả các tệp PDF không ẩn trong thư mục hiện tại.
.ocác tệp và chúng có thể nằm trong các thư mục con. Bạn cũng có thể muốn thêm }{trước print $sumđể tránh in tổng cho mỗi lần lặp. Chúng tôi chỉ muốn cái cuối cùng.
du, và nó sẽ tạo ra nhiềutotaldòng. Ví dụ dưới đây: paste.ubfox.com/23092752