grep đệ quy: loại trừ các thư mục cụ thể


49

Tôi sử dụng grep đệ quy rất nhiều để tìm các tệp nguồn có nội dung cụ thể.

grep -Rni "myfunc" .

Trên các cơ sở mã lớn, điều này có thể bị chậm, vì vậy tôi sử dụng --incldue để hạn chế / mở rộng danh sách trắng.

grep -Rni --include=*.java "myfunc" .

Tuy nhiên, sẽ hiệu quả hơn nếu loại trừ (cắt tỉa) toàn bộ các thư mục con, tôi nghĩ:

grep -Rni --exclude=/.svn/ "myfunc" .

Nhưng --exclude chỉ hỗ trợ các mẫu tệp như * .java ở trên. Làm thế nào tôi có thể loại trừ các thư mục?

Câu trả lời:


10

Bạn có thể nhìn vào ack .

Tôi mới bắt đầu sử dụng nó nhưng có vẻ phù hợp cho việc này.


ack có vẻ khá tốt tốt đẹp là nó trực quan loại trừ các tập tin không mong muốn. tùy chọn --nogroup cung cấp một đầu ra tương tự như grep -Rni
gabor

2
Ack hơi chậm. Bạn có thể thử The Silver Searcher (Ag) hoặc ripgrep (rg).
dùng31389

62
grep -r --exclude-dir=dev --exclude-dir=sys --exclude-dir=proc PATTERN data

Nguồn: https://stackoverflow.com/questions/2799246/grep-excluding-a-specific-folder-USE


17
Lưu ý rằng điều này đệ quy loại trừ. ./devsẽ bị loại trừ CONGNG VỚI ./foo/bar/dev. Sử dụng --exclude-dir=./devđể chỉ áp dụng cho trường hợp đầu tiên.
Cory Walker

4
Bạn cũng có thể rút ngắn điều này một chút bằng cách tạo khối: bash grep -r --exclude-dir={dev,sys,proc} PATTERN data Vấn đề duy nhất với Globing là tôi không thể làm cho nó hoạt động trong bash của mình. Trong trường hợp đó tôi phải giữ chúng riêng biệt.
b01

3
Cũng lưu ý rằng {} chỉ hoạt động nếu bạn đặt nhiều hơn 1 mục, điều đó có nghĩa là --exclude-dir = {home, .svn} là hoạt động nhưng --exclude-dir = {. Svn} sẽ không hoạt động. Thật lãng phí thời gian của tôi để tìm hiểu tại sao {} không hoạt động vì tôi kiểm tra với 1 mục ở vị trí đầu tiên.
林果

Nếu bạn sử dụng {}với một mục duy nhất, có lẽ bạn cần một dấu phẩy đơn để biến nó thành một mảng (không chắc Bash xử lý như thế nào). Thay vì làm điều đó, cuối cùng tôi đã tạo một bí danh trong .bash_aliases lặp lại danh sách các thư mục mà tôi thường muốn loại trừ, ví dụ: .git, .svn, .hg, .cache và sau đó tôi thêm chúng qua một vòng lặp với --exclude-dir $dirvà sau đó mở rộng mảng đó thành bí danh grep.
dragon788

6

bạn có thể sử dụng find thay thế:

find . -not -path "*/.svn*" -not -type d -exec grep -ni "myfunc" {} \; -print

OK, do đó, hơi ngược, bạn sẽ nhận được kết quả grep trước và sau đó là đường dẫn. Có lẽ ai khác có một câu trả lời tốt hơn?


3
ok, tôi thích điều đó rất nhiều tất nhiên tìm thấy là linh hoạt hơn rất nhiều. sự khác biệt duy nhất giữa đầu ra là "grep -Rni" sẽ in tên tệp cho mỗi trận đấu, trong khi "find -exec grep" sẽ in tên tệp trên một dòng và sau đó một dòng cho mỗi trận đấu (với số dòng và nội dung dòng ). sử dụng "grep -Hni" buộc tên tệp được hiển thị trên mỗi dòng
gabor

Cảm ơn bạn đã cung cấp câu trả lời duy nhất hoạt động cho các hệ thống độc hại này, không có grep --exclude-dir, nhưng vẫn phải được thực hiện
Dmitri DB

2

Đây là một ví dụ đầy đủ từ một tập lệnh trong một trong các dự án của tôi có thể giúp ích, tôi gọi tệp này là "all_source" (được đánh dấu là có thể thực thi được) và đặt nó vào thư mục gốc của dự án của tôi, sau đó gọi nó giống như grep myfunc $(./all_source)sắp xếp ở cuối tập lệnh không bắt buộc.

#!/bin/bash

find . \
    -type d \( \
            -wholename './lib' -o \
            -wholename './vc6' -o \
            -name 'gen' -o \
            -name '.svn' \
            \) -prune -o \
    -type f \( \
            -name '*.h' -o \
            -name '*.cpp' -o \
            -name '*.c' -o \
            -name '*.lua' -o \
            -name '*.*awk' \) -print \
    | sort

Kịch bản lệnh này trả về tất cả các tên tệp trong dự án khớp *.h, *.cpp, *.c, *.lua, *.*awk, nhưng không tìm kiếm trong tất cả các thư mục có tên .svn và thư mục gen cũng như bỏ qua các thư mục cho ./lib./vc6(nhưng chỉ các thư mục ngay bên ngoài gốc của dự án). Vì vậy, khi bạn làm điều grep myfunc $(./all_source)đó chỉ greps trong các tập tin. Bạn sẽ cần phải gọi nó từ thư mục gốc của dự án.


0

Ngoài ra còn có tùy chọn -prune để tìm:

 find . -path "*/.svn*" -prune -o -not -type d -exec grep -ni "myfunc" {} \; -print

0

Bạn có thể thử làm điều này:

grep -R  "myfunc" . | grep -v path_to_exclude/

Ví dụ: Nếu bạn không muốn tìm kiếm nội dung trong tệp nhật ký, chỉ cần làm như sau:

grep -R "myfunc" . | grep -v log/
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.