2014-04-21 15 views
23

Tôi cần phải tìm (hay cụ thể hơn, đếm) tất cả các file phù hợp với mô hình này:.đệ quy tìm tất cả các file phù hợp với một khuôn mẫu nhất định

*/foo/* doc

Trường hợp dấu ký tự đại diện đầu tiên bao gồm một số lượng các thư mục con khác nhau.

+1

Nó có bị bash không? zsh có thể làm điều này bằng cách sử dụng cú pháp 'ls **/foo/*. doc'. – Alastair

+0

Alastair, cảm ơn đề nghị. Tôi đã không nhận thức được zsh và cú pháp dấu hoa thị kép của nó. Thật thú vị, nó xuất hiện danh sách đối số mở rộng kết quả là quá dài cho ls (khoảng 6000 tên tập tin) và đưa ra một lỗi. – pw222

+0

Bash v4 cũng hỗ trợ cụm từ đệ quy '**'. – tripleee

Trả lời

27

Với gnu tìm thấy bạn có thể sử dụng regex, mà (không giống như -name) phù hợp với toàn bộ đường dẫn:

find . -regex '.*/foo/[^/]*.doc' 

Để chỉ đếm số lượng các tập tin:

find . -regex '.*/foo/[^/]*.doc' -printf '%i\n' | wc -l 

(Mã nguyên nhân dạng %ifind để in số inode thay vì tên tệp, không giống như tên tệp, số inode được đảm bảo không có các ký tự như dòng mới, vì vậy việc đếm là đáng tin cậy hơn nhờ @tripleee cho đề xuất.)

Tôi không biết điều đó có hoạt động trên OSX hay không.

+2

Nối "| wc -l" vào cuối phần này và nó hoàn hảo. – pw222

8

thế nào về:

find BASE_OF_SEARCH/*/foo -name \*.doc -type f | wc -l

Điều này được thực hiện:

  • bắt đầu tại BASE_OF_SEARCH thư mục/
  • nhìn trong tất cả các thư mục đó có một foo thư mục
  • nhìn cho các tập tin có tên là * .doc
  • đếm các dòng o f kết quả (một cho mỗi tập tin)

Lợi ích của phương pháp này:

  • không đệ quy cũng không lặp đi lặp lại (không vòng)
  • thật dễ dàng để đọc, và nếu bạn đưa nó vào trong một kịch bản nó khá dễ dàng để giải mã (regex đôi khi không phải là).

CẬP NHẬT: bạn muốn có độ sâu khác nhau không? ok:

find BASE_OF_SEARCH -name \*.doc -type f | grep foo | wc -l

  • bắt đầu tại BASE_OF_SEARCH thư mục
  • nhìn cho các tập tin được đặt tên như * .doc
  • chỉ hiển thị các dòng kết quả này bao gồm "foo"
  • đếm dòng kết quả (một cho mỗi tệp)

Tùy chọn, bạn có thể lọc ra các kết quả có "foo" trong tệp tên, bởi vì điều này sẽ hiển thị những người quá.

+0

Tác phẩm này hoạt động ngoại trừ việc nó không hoạt động với độ sâu thư mục con biến đổi giữa BASE_OF_SEARCH và foo. Có lẽ tôi không đủ rõ ràng với đặc tả đó. Đó là đủ gần, mặc dù tôi đã có thể hoàn thành nhiệm vụ tôi đặt ra để làm, do đó, một upvote và cảm ơn bạn. – pw222

+0

Bạn nên nhấn mạnh rằng nó không phải đệ quy. Tuy nhiên, điều này thường không cần thiết. Sau đó, nó là một simpe và giải pháp tốt đẹp. Mặc dù nó có thể có vấn đề hiệu suất - không biết. – robsch

+0

Tôi đã thêm một tính năng cho các yêu cầu của bạn – MonkeyWidget

2

chưa được kiểm tra, nhưng thử:

find . -type d -name foo -print | while read d; do echo "$d/*.doc" ; done | wc -l 

tìm thấy tất cả các "foo" thư mục (ở độ sâu khác nhau) (điều này bỏ qua liên kết tượng trưng, ​​nếu đó là một phần của vấn đề bạn có thể thêm chúng); sử dụng vỏ hình cầu để tìm tất cả các tệp ".doc", sau đó đếm chúng.

+0

Vòng lặp 'while' là hoàn toàn dư thừa và có phần dễ bị lỗi. Ngoài ra, ký tự đại diện sẽ không được mở rộng vì nó được trích dẫn. Chỉ cần pipe 'find -print' thành' wc -l'. Tuy nhiên, điều này sẽ vẫn cung cấp cho số lượng sai nếu một tên tập tin có chứa một dòng mới. – tripleee

Các vấn đề liên quan