Tìm thư mục chứa một số lượng tệp nhất định


13

Hy vọng tôi sẽ có thể làm điều này với findlệnh nhưng tôi không thể thấy thử nghiệm nào trong hướng dẫn để làm những gì tôi muốn. Tôi muốn có thể tìm thấy bất kỳ thư mục nào trong thư mục làm việc có chứa ít hơn, nhiều hơn hoặc chính xác số lượng tôi chỉ định.

find . -filecount +10 # any directory with more than 10 entries
find . -filecount 20 # any directory with exactly 20 entries

Nhưng than ôi không có lựa chọn như vậy.


thử một cái gì đó như "ls -al | wc -l | grep"
Vanadis

Câu trả lời:


16

Bạn có thể thử điều này, để có được tên thư mục con và số lượng tệp / thư mục chứa:

find . -maxdepth 1 -type d -exec bash -c "echo -ne '{} '; ls '{}' | wc -l" \;

Nếu bạn muốn làm tương tự cho tất cả các thư mục con (tìm đệ quy), hãy sử dụng thay thế:

find . -type d -exec bash -c "echo -ne '{} '; ls '{}' | wc -l" \;

Để chọn những thư mục có chính xác 10 tệp:

find . -maxdepth 1 -type d -exec bash -c "echo -ne '{} '; ls '{}' | wc -l" \; | 
  awk '$NF==10'

10 trở lên:

find . -maxdepth 1 -type d -exec bash -c "echo -ne '{} '; ls '{}' | wc -l" \; | 
 awk '$NF>=10'

10 hoặc ít hơn:

find . -maxdepth 1 -type d -exec bash -c "echo -ne '{} '; ls '{}' | wc -l" \; | 
 awk '$NF<=10'

Nếu bạn muốn chỉ giữ lại tên thư mục (ví dụ: bạn muốn chuyển nó sang một quy trình khác theo dòng dưới như @evilsoup đề xuất), bạn có thể sử dụng:

find . -maxdepth 1 -type d -exec bash -c "echo -ne '{}\t'; ls '{}' | wc -l" \; | 
 awk -F"\t" '$NF<=10{print $1}'

1
Tôi nghĩ có thể hữu ích khi bao gồm lệnh awk để cắt số lượng tập tin (tức là cột được phân tách bằng khoảng trắng cuối cùng), trong trường hợp người hỏi muốn chuyển đầu ra sang thứ khác.
evilsoup

1
@evilsoup ý tốt, xong.
terdon

Để hỗ trợ khoảng trắng và ký tự đặc biệt trong tên thư mục; hãy thử đảo ngược việc sử dụng các trích dẫn đơn và kép như sau:find . -type d -exec bash -c 'echo -ne "{} "; ls "{}" | wc -l' \; | awk '$NF<=10'
Håvard Geithus

3

Để liệt kê các thư mục con ngay lập tức chứa các tệp chính xác $NUM .

find -maxdepth 2 -mindepth 2 -type f -printf '%h\0' | awk -v num="$NUM" 'BEGIN{RS="\0"} {array[$0]++} END{for (line in array) if (array[line]==num) printf "%s\n", line}'

Để liệt kê các thư mục con ngay lập tức chứa lớn hơn $NUMcác tệp.

find -maxdepth 2 -mindepth 2 -type f -printf '%h\0' | awk -v num="$NUM" 'BEGIN{RS="\0"} {array[$0]++} END{for (line in array) if (array[line]>num) printf "%s\n", line}'

Để liệt kê các thư mục con ngay lập tức chứa ít hơn $NUMcác tệp.

find -maxdepth 2 -mindepth 2 -type f -printf '%h\0' | awk -v num="$NUM" 'BEGIN{RS="\0"} {array[$0]++} END{for (line in array) if (array[line]<num) printf "%s\n", line}'

Các mục được kết thúc bằng ký tự null \0, vì vậy tên tệp chứa dòng mới hoặc các loại khoảng trắng khác sẽ được hiểu chính xác. Các %hbản in của mỗi tập tin dirname. awksau đó sử dụng một mảng để đếm số lần nó gặp mỗi thư mục, in nó nếu điều kiện được đáp ứng.

Xin lưu ý rằng không có lệnh nào nói trên sẽ hiển thị các thư mục chứa tệp không. Cũng lưu ý rằng bằng tệp tôi đang đề cập đến các tệp thông thường, không phải liên kết, thư mục, ổ cắm, khối, ống có tên, vân vân.

Tôi đã cố gắng làm điều này đơn giản nhất có thể. Nếu bạn muốn tìm các thư mục con đệ quy hoặc các tệp trong đó, một lệnh được sửa đổi là bắt buộc. Có quá nhiều khả năng để liệt kê tất cả.


2

Thử đi:

[`tìm. | wc -l` -eq 10] && echo "Đã tìm thấy"

[`tìm. | wc -l` -gt 10] && echo "Đã tìm thấy"

[`tìm. | wc -l` -lt 10] && echo "Đã tìm thấy"

Trong ví dụ này, bạn có thể kiểm tra xem thư mục CURRENT có chứa chính xác 10, nhiều hơn 10 và ít hơn 10 tệp / thư mục hay không. Nếu bạn cần kiểm tra một loạt các thư mục, chỉ cần sử dụng vòng lặp.


Giải pháp của bạn cũng tính thư mục hiện tại ( .), bạn có thể muốn sửa đổi cho phù hợp.
terdon

Tôi thích sự thúc đẩy của câu trả lời này (vì tôi là một kẻ háu ăn khi làm mọi thứ trong vỏ), nhưng tốt hơn hết bạn nên sử dụng wc -l < <(printf %s\\n ./*)hoặc printf %s\\n ./* | wc -ltrong bài kiểm tra, để tránh một findcuộc gọi không cần thiết . Điều này cũng sẽ tránh được vấn đề mà @terdon lưu ý, kể cả .trong kết quả. Tuy nhiên, nó cũng sẽ gặp phải vấn đề bỏ qua các tập tin bắt đầu bằng một .; Tôi sẽ giải quyết vấn đề này bằng shopt -s dotglob(để tạo ra các tập tin khớp với các tập tin bắt đầu bằng một ., nhưng không .hoặc ..).
evilsoup

@terdon Nó không quan trọng. Nó không phải là giải pháp cuối cùng, chỉ là ví dụ, ý tưởng. Bạn có thể -1, hoặc thay đổi 10 thành 11 trong phiên bản cuối cùng.
Tháng Chín

Tôi biết, và ý tưởng là tốt đó là lý do tại sao tôi đưa ra gợi ý.
terdon

@ terdon. Cảm ơn bạn. Có thể có nhiều yêu cầu khác nhau, như: Chỉ đếm các tệp chứ không phải không phải thư mục, hoặc liên kết hoặc liên kết cứng. Đếm hoặc không tập tin trong thư mục con. Đếm các tệp ẩn (như .bashrc) ... ... vì vậy biểu thức của bạn có thể là veeeeery loooong. :)
tháng chín
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.