Làm cách nào để tôi đếm tất cả các tệp đệ quy thông qua các thư mục


47

Tôi muốn xem có bao nhiêu tệp trong thư mục con để tìm ra nơi sử dụng tất cả các nút trên hệ thống. Kiểu như tôi sẽ làm điều này để sử dụng không gian

du -sh /*

Nó sẽ cho tôi không gian được sử dụng trong các thư mục gốc, nhưng trong trường hợp này tôi muốn số lượng tệp chứ không phải kích thước.



Tôi nghĩ rằng "có bao nhiêu tệp trong thư mục con trong thư mục con" là một cấu trúc khó hiểu. Nếu nói rõ hơn những gì bạn muốn, bạn có thể nhận được câu trả lời phù hợp với hóa đơn.
Steven D

@Steven cảm thấy thoải mái khi viết lại nó ... Tôi nghĩ rằng ví dụ của tôi du -sh /*đã làm cho nó khá rõ ràng về cách tôi muốn số đếm hoạt động. Điều tương tự, chỉ cần đếm các tập tin không phải là byte.
xenoterracide

Khi bạn đề cập đến việc sử dụng inode, tôi không hiểu bạn muốn đếm số lượng tệp hoặc số lượng nút được sử dụng. Hai là khác nhau khi liên kết cứng có mặt trong hệ thống tập tin. Hầu hết, nếu không phải tất cả, câu trả lời cho số lượng tệp. Đừng sử dụng chúng trên đĩa sao lưu Apple Time Machine.
mouviciel

@mouviciel cái này không được sử dụng trên đĩa sao lưu và vâng tôi cho rằng chúng có thể khác nhau, nhưng trong môi trường tôi có rất ít liên kết cứng, về mặt kỹ thuật tôi chỉ cần cảm nhận về nó. tìm ra nơi mà một người nào đó đang đốt cháy trong đó hạn ngạch inode.
xenoterracide

Câu trả lời:


60
find -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done

Cảm ơn Gilles và xenoterracide để sửa lỗi an toàn / tương thích.

Phần đầu tiên: find -maxdepth 1 -type dsẽ trả về một danh sách tất cả các thư mục trong thư mục làm việc hiện tại. Điều này được dẫn đến ...

Phần thứ hai: while read -r dir; dobắt đầu một vòng lặp while - miễn là đường ống đi vào while được mở (cho đến khi toàn bộ danh sách các thư mục được gửi), lệnh read sẽ đặt dòng tiếp theo vào biến "dir". Rồi nó tiếp tục ...

Phần thứ ba: printf "%s:\t" "$dir";sẽ in chuỗi trong "$ dir" (đang giữ một trong các tên thư mục) theo sau là một tab.

Phần thứ tư: find "$dir -f file"tạo một danh sách tất cả các tệp bên trong tên thư mục được giữ trong "$ dir". Danh sách này được gửi đến ..

Phần thứ năm: wc -l;đếm số lượng dòng được gửi vào đầu vào tiêu chuẩn của nó.

Phần cuối cùng: donechỉ đơn giản là kết thúc vòng lặp while.

Vì vậy, chúng tôi nhận được một danh sách tất cả các thư mục trong thư mục hiện tại. Đối với mỗi thư mục đó, chúng tôi tạo một danh sách tất cả các tệp trong đó để chúng tôi có thể đếm tất cả chúng bằng cách sử dụng wc -l. Kết quả sẽ như sau:

./dir1: 234
./dir2: 11
./dir3: 2199
...

Luôn luôn sử dụng read -rnhư readxử lý dấu gạch chéo ngược đặc biệt. Sau đó echo -en "$dir:\t"sẽ một lần nữa dấu gạch chéo ngược; một sửa chữa đơn giản là sử dụng printf '%s:\t' "$dir"thay thế. Tiếp theo, $dirnên "$dir"( luôn luôn sử dụng dấu ngoặc kép xung quanh thay thế biến ).
Gilles 'SO- ngừng trở nên xấu xa'

sửa đổi theo đề xuất @Gilesfind -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" | wc -l; done
xenoterracide

2
Tôi đang thêm sort -n -r -k2vào cuối này, cho rất nhiều thư mục, để tôi biết nơi sử dụng nhiều nhất
xenoterracide

Phần thứ tư: find "$ dir" tạo một danh sách tất cả các tệp bên trong tên thư mục được giữ trong "$ dir". Bạn đã quên thêm -type fvào để làm cho nó liệt kê các tập tin:find -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done
Krzysztof Boduch

@ krzysiek-boduch Cảm ơn! Tôi cập nhật câu trả lời.
Shawn J. Goff

15

Hãy thử find . -type f | wc -l, nó sẽ đếm tất cả các tệp trong thư mục hiện tại cũng như tất cả các tệp trong thư mục con. Lưu ý rằng tất cả các thư mục sẽ không được tính là tệp, chỉ các tệp thông thường mới làm.


13

Đây là phần tổng hợp một số lệnh liệt kê hữu ích (được băm lại dựa trên mã người dùng trước đó):

Liệt kê các thư mục có số tập tin:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type f | wc -l); printf "%4d : %s\n" $n "$dir"; done

Liệt kê các thư mục có số tập tin khác không:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type f | wc -l); if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

Liệt kê các thư mục có số lượng thư mục con:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type d | wc -l); let n--; printf "%4d : %s\n" $n "$dir"; done

Liệt kê các thư mục có số lượng thư mục con khác không:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" -type d | wc -l); let n--; if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

Liệt kê các thư mục trống:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" | wc -l); let n--; if [ $n -eq 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

Liệt kê các thư mục không trống với số lượng nội dung:

find -maxdepth 1 -type d | sort | while read -r dir; do n=$(find "$dir" | wc -l); let n--; if [ $n -gt 0 ]; then printf "%4d : %s\n" $n "$dir"; fi; done

Và btw .. nếu bạn muốn có đầu ra của bất kỳ lệnh nào trong danh sách này được sắp xếp theo số lượng vật phẩm .. chuyển lệnh thành một sắp xếp: "a-list-lệnh" | sort -n
DolphinDream

12

Thử:

find /path/to/start/at -type f -print | wc -l

làm điểm bắt đầu hoặc nếu bạn thực sự chỉ muốn truy xuất lại thông qua các thư mục con của thư mục (và bỏ qua các tệp trong thư mục cấp cao nhất đó)

find `find /path/to/start/at -mindepth 1 -maxdepth 1 -type d -print` -type f -print | wc -l

+1 cho một cái gì đó | wc -l ... đếm từ là một công cụ nhỏ bé tuyệt vời
Johan

vâng nhưng điều này chỉ có 1 thư mục .... Tôi muốn lấy số lượng cho tất cả các thư mục trong một thư mục và tôi không muốn chạy nó một cách riêng biệt mỗi lần ... tất nhiên tôi cho rằng tôi có thể sử dụng một vòng lặp ... nhưng tôi đang lười biếng.
xenoterracide

findlàm việc đệ quy thông qua tất cả các thư mục con theo mặc định. Nếu bạn muốn nó hoạt động ở nhiều vị trí, bạn có thể chỉ định tất cả chúng ở giữa find-type.
Didier Trosset

cái thứ hai chắc chắn không hoạt động .... Tôi đã thử nó trên / nhà. Tôi nhận được 698035 . Tôi sẽ thấy khoảng 6 số.
xenoterracide

Nó hoạt động với tôi - bạn có chắc bạn chỉ có 6 tệp bên dưới /home? Tôi chắc chắn 100% bạn không.
Khóc Havok

4

Giải pháp sau đây đếm số lượng thực tế của các nút được sử dụng bắt đầu từ thư mục hiện tại:

find . -print0 | xargs -0 -n 1 ls -id | cut -d' ' -f1 | sort -u | wc -l

Để lấy số lượng tệp của cùng một tập hợp con, hãy sử dụng:

find . | wc -l

Đối với các giải pháp chỉ khám phá các thư mục con, mà không đưa vào các tệp tài khoản trong thư mục hiện tại, bạn có thể tham khảo các câu trả lời khác.


1
Ý tưởng tốt lấy các liên kết cứng vào tài khoản. Giả sử GNU tìm thấy, bạn không cần quá nhiều bước : find -printf '%i\n' | sort -u | wc -l. Nếu bạn muốn di động, find . -exec ls -id {} + | cut …thay vào đó bạn cần .
Gilles 'SO- ngừng trở nên xấu xa'

2

OS X 10.6 cuộn cảm với lệnh trong câu trả lời được chấp nhận, vì nó không chỉ định đường dẫn cho find. Thay vào đó sử dụng:

find . -maxdepth 1 -type d | while read -r dir; do printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done

2

Tôi biết tôi đến bữa tiệc muộn, nhưng tôi tin rằng giải pháp thuần túy này bash(hoặc vỏ khác chấp nhận sao đôi toàn cầu) có thể nhanh hơn nhiều trong một số tình huống:

shopt -s globstar    # to enable ** glob in bash
for dir in */; do a=( "$dir"/**/* ); printf "%s\t%s\n" "$dir:" "${#a[*]}"; done

đầu ra:

d1/:    302
d2/:    24
d3/:    640
...

1

Hãy thử xem:

find -type d -print0 | xargs -0 -I {} sh -c 'printf "%s\t%s\n" "$(find "{}" -maxdepth 1 -type f | wc -l)" "{}"'

Nó sẽ hoạt động tốt trừ khi tên tập tin bao gồm dòng mới.


cách quá đệ quy ... Tôi chỉ muốn xem cấp cao nhất, nơi nó tổng hợp mọi thứ bên dưới nó. tổng cộng ... điều này kết thúc việc in mọi thư mục.
xenoterracide

@xenoterracide: Hãy thử thêm -maxdepth 1ngay sau lần đầu tiên find. Nếu bạn muốn bao gồm số lượng thư mục con trong số của bạn, hãy xóa phần -type fcuối (điều đó thực sự phải có ! -type d, vì vậy tất cả các tệp không phải là thư mục sẽ được đưa vào).
Dennis Williamson

1

Nếu bạn đã ncducài đặt (phải có khi bạn muốn dọn dẹp), chỉ cần gõ cvào "Chuyển đổi hiển thị số lượng mục con". Và Cđể "Sắp xếp theo các mục".


1
lol, đây phải là câu trả lời được chấp nhận nhiều nhất :)
x-yuri

0

du --inodes

Tôi không chắc tại sao không ai (bao gồm cả tôi) biết:

du --inodes
--inodes
      list inode usage information instead of block usage

Tôi khá chắc chắn rằng điều này giải quyết vấn đề của OP. Tôi đã bắt đầu sử dụng nó rất nhiều để tìm ra nơi chứa tất cả rác trong các ổ đĩa lớn của mình (và giảm tải nó vào một đĩa cũ hơn).

Thêm thông tin

Nếu bạn không muốn lặp lại (có thể hữu ích trong các tình huống khác), hãy thêm

-S, --separate-dirs
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.