Nếu bạn sử dụng -r
, có lẽ bạn muốn tìm kiếm đệ quy chỉ thư mục hiện tại :
grep -r 'class MyClass' .
Lưu ý khoảng thời gian kết thúc ở trên.
Những gì bạn nói grep
là bạn muốn nó tìm kiếm đệ quy mọi *.php
tệp hoặc thư mục , nhưng bạn có thể không có bất kỳ thư mục nào kết thúc bằng một phần mở rộng .php. Trên đây là cách đơn giản nhất có thể để thực hiện tìm kiếm nhưng cũng bao gồm các tệp thuộc loại khác, đặc biệt có vấn đề khi bạn có các thư mục .svn ở mọi nơi. Nếu bạn không có nhiều loại tệp khác, thì ở trên nói chung là đủ và hoạt động tốt.
Hầu hết các hiện thân của grep không có cách chỉ định các phần mở rộng tệp có thể được tìm kiếm, vì vậy bạn thường sử dụng find kết hợp với nó:
find <startDir> -iname '*.php' -exec grep 'class[ \t]*MyClass' {} \;
-iname
nói với một số phiên bản của grep mà bạn muốn thực hiện tìm kiếm tên tệp không phân biệt chữ hoa chữ thường, nhưng nhiều biến thể không phải của GNU không hỗ trợ nó, vì vậy bạn có thể sử dụng -name
thay thế.
Các -exec
tùy chọn ở trên có tác dụng phụ của cách gọi grep cho mỗi tập tin, mà là khá tốn kém.
Các phiên bản khác của grep hỗ trợ một lệnh +
tìm kiếm để nối các đối số lại với nhau để giảm số lần gọi của tệp thực thi:
find <startDir> -iname '*.php' -exec grep 'class[ \t]*MyClass' {} + \;
Một cách thường xuyên được đề xuất để giảm các yêu cầu là sử dụng xargs sẽ bắn grep ít nhất có thể nhưng nhiều lần nếu cần:
find <startDir> -iname \*.php | xargs grep "class[ \t]*MyClass"
xargs
đủ thông minh để vượt qua grep đến số lượng đối số tối đa được hỗ trợ trên dòng lệnh, nhưng biến thể trên không xử lý tốt các ký tự nhất định như khoảng trắng. Ví dụ: 'file.php', tên tệp grep sẽ nhận 'the' làm đối số và 'file.php' làm đối số để cả hai sẽ không được tìm thấy. Thay vào đó chúng tôi sử dụng:
find <startDir> -iname \*.php -print0 | xargs -0 grep "class[ \t]*MyClass"
print0
và -0
làm việc cùng nhau và sử dụng các đối số theo sau bởi một ký tự null để đối số được xác định hoàn toàn và rõ ràng.
Nếu bạn có nhiều hơn một khoảng trắng sau class
hoặc một tab, bạn có thể muốn cho phép nhiều ký tự hơn bằng cách thay đổi biểu thức chính:class[ \t]*MyClass
Bài đăng này trên StackOverflow có các ví dụ khác và giải thích cách loại trừ các thư mục nhất định, như thư mục .svn.
grep -r
không cung cấp cho bạn.