Loại trừ một thư mục con sử dụng find


115

Tôi có cấu trúc thư mục như thế này

data
|___
   |
   abc
    |____incoming
   def
    |____incoming
    |____processed
   123
    |___incoming
   456
    |___incoming
    |___processed

Có một thư mục con đến trong tất cả các thư mục bên trong thư mục Dữ liệu. Tôi muốn nhận tất cả các tệp từ tất cả các thư mục và thư mục con ngoại trừ các thư mục def / đến và 456 / đến. Tôi đã thử với lệnh sau

 find /home/feeds/data -type d \( -name 'def/incoming' -o -name '456/incoming' -o -name arkona \) -prune -o -name '*.*' -print

nhưng nó không hoạt động như mong đợi.

Ravi


3
Đây không phải là lời khuyên tốt, nhưng nó sẽ giúp bạn thoát khỏi nhiều tình huống nhanh chóng và bẩn thỉu: đường ống grep -v somethingđể loại trừ bất cứ điều gì bạn không muốn
Miquel

Câu trả lời:


206

Những công việc này:

find /home/feeds/data -type f -not -path "*def/incoming*" -not -path "*456/incoming*"

Giải trình:

  • find /home/feeds/data: bắt đầu tìm đệ quy từ đường dẫn đã chỉ định
  • -type f: chỉ tìm tệp
  • -not -path "*def/incoming*": không bao gồm bất cứ điều gì với def/incomingmột phần của đường dẫn của nó
  • -not -path "*456/incoming*": không bao gồm bất cứ điều gì với 456/incomingmột phần của đường dẫn của nó

gặp lỗi "find: bad option -not find: path-list vị ngữ danh sách"
Ravi

@Ravi bạn đang sử dụng bash shell? Tôi chỉ thử nghiệm điều này trên thiết bị đầu cuối của tôi và nó hoạt động cho tôi. Thay vào đó, hãy thử sao chép và dán giải pháp nếu bạn đã sửa đổi tập lệnh của mình.
sampson-chen

Nó hoạt động, nhưng, nó liệt kê các dir không tập tin trong các dir đó.
Ravi

1
-pathkhớp với toàn bộ chuỗi, vì vậy nếu bạn đang thực hiện find ., thì -pathchuỗi của bạn cần phải là./path/to/directory/*
Heath

1
FYI -not -pathchắc chắn sẽ hoạt động trong ví dụ này nhưng findvẫn lặp trong cấu trúc thư mục và sử dụng các chu kỳ cpu để lặp lại trên tất cả các thư mục / tệp đó. để ngăn chặn việc findlặp lại các thư mục / tệp đó (có thể có hàng triệu tệp ở đó) thì bạn cần sử dụng -prune( -prunetuy nhiên tùy chọn này khó sử dụng).
Trevor Boyd Smith

9

Chỉ vì mục đích tài liệu: Bạn có thể phải đào sâu hơn vì có nhiều chòm sao tìm kiếm (như tôi phải làm). Nó có thể prunelà bạn của bạn trong khi -not -pathsẽ không làm những gì bạn mong đợi.

Vì vậy, đây là một ví dụ có giá trị trong 15 ví dụ tìm loại trừ các thư mục:

http://www.theunixschool.com/2012/07/find-command-15-examples-to-exclude.html

Để liên kết đến câu hỏi ban đầu, loại trừ cuối cùng đã làm việc cho tôi như thế này:

find . -regex-type posix-extended -regex ".*def/incoming.*|.*456/incoming.*" -prune -o -print 

Sau đó, nếu bạn muốn tìm một tệp và vẫn loại trừ các đường dẫn, chỉ cần thêm | grep myFile.txt.

Nó cũng có thể phụ thuộc vào phiên bản tìm kiếm của bạn. Tôi hiểu rồi:

$ find -version
GNU find version 4.2.27
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION SELINUX

5

-namechỉ khớp với tên tệp, không phải toàn bộ đường dẫn. Bạn muốn sử dụng -paththay thế, cho các phần mà bạn đang cắt tỉa các thư mục như thế nào def/incoming.


2
find $(INP_PATH} -type f -ls |grep -v "${INP_PATH}/.*/"

7
Một số giải thích có thể làm cho điều này thành một câu trả lời tốt hơn nhiều.
Cris Luengo

Cảm ơn bạn vì đoạn mã này, có thể cung cấp một số trợ giúp ngắn hạn có giới hạn. Một lời giải thích phù hợp sẽ cải thiện đáng kể giá trị lâu dài của nó bằng cách chỉ ra lý do tại sao đây là một giải pháp tốt cho vấn đề và sẽ giúp nó hữu ích hơn cho những người đọc tương lai với những câu hỏi tương tự khác. Vui lòng chỉnh sửa câu trả lời của bạn để thêm một số lời giải thích, bao gồm các giả định bạn đã đưa ra
Shawn C.

1
Lưu ý: Thủ thuật này không hoạt động nếu một người sử dụng find ... -print0kết hợp với sau nàyxargs -0
phs

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.