Thư mục tìm kiếm đệ quy nhưng loại trừ thư mục con svn


10

Tôi muốn tìm tất cả các lần xuất hiện footrong một hệ thống tệp lớn được duy trì bởi SVN nhưng tôi không muốn khớp bất kỳ thứ gì có trong bất kỳ .svnthư mục nào .

Tôi nhận được kết quả khớp ngay lập tức khi tôi làm grep -l -e 'foo' *nhưng khi tôi thử và loại trừ các thư mục svn bằng grep -l -e 'foo' --exclude-dir=".svn"lệnh chỉ bị treo.

Tôi đang làm gì sai?

Câu trả lời:


11

--exclude-dirkhông thay thế nhu cầu liệt kê các tập tin trên dòng lệnh. Bạn đang "treo" vì grepđang chờ đầu vào tiêu chuẩn.

grep -l -e 'foo' --exclude-dir = ". svn" *

Xem xét sử dụng ack , loại trừ .svnvà các thư mục tương tự (và có nhiều tính năng khác) theo mặc định.


2
Trình dọn dẹp nếu bạn thay đổi *thành ., trong trường hợp có các thư mục ẩn khác cần tìm kiếm.
Kevin

hoặc có lẽ bạn muốn sử dụng --recursive .thay vào đó, xem như OP đã có GNU grep.
jw013

Cá nhân, tôi có shopt -s dotglobtrong Bash, vì vậy *đã chứa các tệp chấm. -rcũng tốt, nhưng ackmặc định cũng vậy :)
ephemient

5

Bạn có thể quan tâm đến ack . Nó thực hiện tìm kiếm đệ quy (và các hoạt động giống như grep khác) và loại trừ các thư mục như .svn hoặc .git theo mặc định.


Theo dõi về điều này, tôi hiện đang sử dụng ag, tương tự, nhưng nhanh hơn.
WhyNotHugo

2

Các grep --exclude-dir...giải pháp nên được tốt, nhưng chỉ để hiển thị một cách khác, bạn có thể làm điều này với find's -prune:

find -name .svn -prune -o -type f -exec grep -l "$pattern" {} +

Nếu bạn muốn thực hiện một cái gì đó xa hơn, findtốt hơn là đơn giản grep -r:

find -name .svn -prune -o -type f -exec grep -q "$pattern" {} \; -exec ./process {} \;

1

Nếu bạn không muốn grep vào các thư mục như .svn bao giờ, bạn có thể đặt $GREP_OPTIONSbiến để loại trừ nó như dưới đây:

export GREP_OPTIONS="--exclude-dir=\*/.svn/\*"

Chỉ cần thêm dòng này vào .bashrcgreps đệ quy của bạn và sẽ không còn nhập vào các .svnthư mục. Tất nhiên, nó có thể phong phú như bạn muốn:

export GREP_OPTIONS="--exclude-dir=\*/.svn/\* --exclude-dir=\*/.hg/\* --exclude-dir=\*/.git/\* --exclude=\*~"

1
Cá nhân tôi làm điều này bằng cách sử dụng một bí danh để tôi có thể bỏ qua danh sách loại trừ nếu tôi thực sự cần tìm kiếm bên trong các thư mục đó, tôi chỉ có thể sử dụng grep trần mà không cần phải bỏ / bỏ biến. Nó cũng cho phép tôi duy trì một danh sách các thư mục mà tôi có thể dễ dàng mở rộng và tự động thêm vào danh sách loại trừ của mình mà không cần phải gõ thêm.
dragon788

Đó là một cách tiếp cận tốt. Nó cũng có lợi thế là, nếu bạn cần grep vào các thư mục, bạn sẽ không quên bạn đặt một biến. (Không phải là tôi đã bao giờ cần thiết để grep họ.) Nhưng TBH những ngày này tôi sử dụng ag (một clone ack) cho những việc này ^^
brandizzi

0

Đây cũng là một giải pháp tuyệt vời:

find . | awk '$0 !~ /.svn/{print}' | awk '/foo/{print}'

Về cơ bản, từ tất cả các tệp, lược bớt những tệp khớp với /.svn/ và sau đó, trong số đó, chỉ in những tệp khớp với / foo /. Tôi cũng thích giải pháp này vì bạn có thể dễ dàng sử dụng kết quả với ls. Ví dụ: bạn có thể sử dụng

ls -tl $(find . | awk '$0 !~ /.svn/{print}' | awk '/foo/{print}')

để xem chế độ xem danh sách được sắp xếp theo ngày sửa đổi. Ngoài ra, thật tuyệt khi có đường dẫn đầy đủ về kết quả nếu bạn muốn làm gì đó với chúng (mở chúng, thực thi, v.v.)

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.