2012-07-19 30 views
10

Tôi đang sử dụng thành công việc tìm kiếm để tạo danh sách tất cả các tệp trong thư mục con hiện tại, ngoại trừ các tệp trong thư mục con "bộ nhớ cache". Đây là đoạn mã đầu tiên của tôi:Đường ống tìm kết quả vào grep để loại trừ thư mục nhanh

find . -wholename './cach*' -prune -o -print 

Bây giờ tôi muốn đặt lệnh này vào lệnh grep. Có vẻ như đơn giản như vậy:

find . -wholename './cach*' -prune -o -print | xargs grep -r -R -i "samson" 

... nhưng đây là kết quả trả về chủ yếu từ thư mục bộ nhớ cache. Tôi đã thử loại bỏ các tham chiếu xargs, nhưng điều đó làm những gì bạn mong đợi, chạy grep trên văn bản của tên tập tin, thay vì trên các tập tin mình. Mục tiêu của tôi là tìm "samson" trong bất kỳ tệp nào không có nội dung được lưu trong bộ nhớ cache.

Có lẽ tôi sẽ giải quyết vấn đề này bằng cách chỉ sử dụng số lần tăng gấp đôi trong trường hợp này, nhưng tôi rất tò mò về lý do tại sao một lớp lót này hoạt động theo cách này. Tôi rất muốn nghe suy nghĩ về một cách để sửa đổi nó trong khi vẫn sử dụng hai lệnh này (vì có lợi thế về tốc độ để thực hiện theo cách này).

(Đây là trong CentOS 5, btw.)

Trả lời

9

Trận đấu wholename thể là lý do tại sao nó vẫn bao gồm "bộ nhớ cache" tập tin. Nếu bạn đang thực thi lệnh find trong thư mục chứa thư mục "bộ nhớ cache", nó sẽ hoạt động. Nếu không, hãy thử thay đổi nó thành -name '*cache*' để thay thế.

Ngoài ra, bạn không cần -r hoặc -R cho số grep của bạn, yêu cầu nó recurse thông qua thư mục - nhưng bạn đang thử nghiệm các tệp riêng lẻ.

Bạn có thể cập nhật lệnh của bạn sử dụng phiên bản đường ống, hoặc một đơn lệnh:

find . -name '*cache*' -prune -o -print0 | xargs -0 grep -il "samson" 

hoặc

find . -name '*cache*' -prune -o -exec grep -iq "samson" {} \; -print 

Lưu ý, các -l trong lệnh đầu tiên kể grep để "liệt kê các tập tin "và không phải là dòng phù hợp. Các -q trong thứ hai không giống nhau; nó yêu cầu grep trả lời một cách lặng lẽ để find sau đó sẽ chỉ in tên tệp.

+0

Cảm ơn! Việc loại bỏ đệ quy là những gì đã làm các trick cho tôi. Ngẫu nhiên, đó là một sự nhầm lẫn về phía tôi, vì tôi thường sử dụng "-r-i -I", điều này có ý nghĩa hơn nhiều so với các cờ đệ quy dư thừa.) Phần "wholename" là tốt, vì thư mục con không mong muốn thực sự ở cấp thư mục gốc của thư mục hiện hành. Vì vậy, bây giờ là: 'tìm. -wholename './cach*' -prune -o -print | xargs grep -i -I "samson" ' – eternalnewb

+0

Tuyệt vời, vui vì nó là cái gì đó đơn giản =] – newfurniturey

3

Sử dụng tùy chọn -exec trên tìm thay vì đường ống họ lệnh khác. Từ đó bạn có thể sử dụng grep "samson" {} \; để tìm samson trong mỗi tệp được liệt kê.

Ví dụ:

find . -wholename './cach*' -prune -o -exec grep "samson" "{}" + 
3

Bạn đã tự yêu cầu grep chấp nhận lại (hai lần! -r-R là từ đồng nghĩa). Vì một trong các đối số bạn đang truy cập là . (thư mục trên cùng), grep đang tìm kiếm trong mọi tệp (một số trong số chúng hai lần hoặc thậm chí nhiều hơn nếu chúng ở trong thư mục con).

Nếu bạn đang đi để sử dụng findgrep, làm điều này:

find . -path './cach*' -prune -o -print0 | xargs -0 grep -i "samson" 

Sử dụng -print0-0 làm cho công việc kịch bản của bạn ngay cả với tên file có chứa khoảng trắng hoặc ký tự chấm câu.

Tuy nhiên, có thể bạn không cần phải bận tâm với find ở đây, vì GNU grep có khả năng loại trừ các thư mục:

grep -R --exclude-dir='cach*' -i "samson" . 

(Điều này cũng không bao gồm ./deeply/nested/directory/cache Nếu bạn chỉ muốn loại trừ thư mục bộ nhớ cache tại. toplevel, sử dụng find như bạn đã làm.)

+0

Nếu có quá nhiều tệp trong thư mục/đường dẫn hiện tại, thì' grep' sẽ trả về lỗi "quá nhiều đối số" - vì vậy bạn sẽ cần phải cẩn thận với điều đó một mình. – newfurniturey

+0

Cảm ơn bạn đã đánh bắt! Như đã đề cập trong câu trả lời "được chấp nhận", hãy dọn dẹp những thứ cố định ngay lập tức. Các bạn rất tuyệt. – eternalnewb

+0

@newfurniturey Không, lỗi “quá nhiều đối số” sẽ xuất phát từ trình bao, nếu dòng lệnh quá dài (ví dụ: nếu tôi viết 'grep… *' và có rất nhiều tệp). Ở đây không có shell globbing, dòng lệnh chính xác là 43 ký tự. – Gilles

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