Khi tôi muốn tìm kiếm toàn bộ cây cho một số nội dung, tôi sử dụng
find . -type f -print0 | xargs -0 grep <search_string>
Có cách nào tốt hơn để làm điều này về hiệu suất hoặc ngắn gọn?
Khi tôi muốn tìm kiếm toàn bộ cây cho một số nội dung, tôi sử dụng
find . -type f -print0 | xargs -0 grep <search_string>
Có cách nào tốt hơn để làm điều này về hiệu suất hoặc ngắn gọn?
Câu trả lời:
Kiểm tra xem bạn grephỗ trợ -rtùy chọn (ví recurse ):
grep -r <search_string> .
--exclude-dirđể giải quyết hiệu suất và chúng tôi có một người chiến thắng!
greptrên các bản phân phối FreeBSD và Linux gần đây hỗ trợ nó. Và tại sao --exclude-dir? Bạn không yêu cầu tìm kiếm toàn bộ một cây ?
--exclude-dirthực sự tiện dụng trong trường hợp sử dụng của tôi (vì các phần của cây con rất lớn, nhưng vô dụng) và tôi đã hỏi về hiệu suất ... nhưng bạn nói đúng, không cần thiết.
--exclude-dirlà độc quyền cho GNU grep. (-:
Một câu trả lời tối ưu phụ: Thay vì dẫn đầu ra findvào grep, bạn chỉ có thể chạy
find . -type f -exec grep 'research' {} '+'
và voila, một lệnh thay vì hai!
giải trình :
find . -type f
tìm tất cả các tập tin thường xuyên trong
-exec grep 'research'
grep 'nghiên cứu'
{}
trong tên tập tin được tìm thấy
'+'
sử dụng một lệnh cho tất cả các tên tệp, không chỉ một lần cho mỗi tên tệp.
Nb: với ';'nó sẽ có một lần cho mỗi tên tệp.
Ngoài ra, nếu bạn sử dụng điều đó để xử lý mã nguồn, bạn có thể xem xét ack, điều này được thực hiện để tìm kiếm các bit mã dễ dàng.
Chỉnh sửa :
Bạn có thể mở rộng nghiên cứu đó một chút. Đầu tiên, bạn có thể sử dụng -name ''chuyển đổi findđể tìm kiếm các tệp có mẫu đặt tên cụ thể.
Ví dụ :
chỉ các tệp tương ứng với nhật ký: -name '*.log'
chỉ các tệp tương ứng với các tiêu đề c, nhưng bạn không thể gắn với chữ hoa hoặc chữ thường cho phần mở rộng tên tệp của mình: -iname *.c
Nb: like for grepvà ack, -iswitch có nghĩa là trường hợp không nhạy cảm trong trường hợp này.
Trong trường hợp đó, grep sẽ hiển thị mà không có màu và không có số dòng.
Bạn có thể thay đổi điều đó với --colorvà các -ncông tắc (Số màu và số dòng trong tệp tương ứng).
Cuối cùng, bạn có thể có một cái gì đó như:
find . -name '*.log' -type f -exec grep --color -n 'pattern' {} '+'
ví dụ
$ find . -name '*.c' -type f -exec grep -n 'hello' {} '+'
./test2/target.c:1:hello
-name '*.log'Nó nhanh hơn.
Nếu bạn muốn lặp lại thành các thư mục con:
grep -R 'pattern' .
Các -Rtùy chọn không phải là một lựa chọn tiêu chuẩn, nhưng được hỗ trợ bởi hầu hết các chung greptriển khai.
-rthay vì -Rbỏ qua các liên kết tượng trưng khi GNU grep có liên quan
greptriển khai GNU hiện tại bắt được các cuộc thu hồi, tôi nghĩ vậy. Nếu không, nó phụ thuộc vào những gì bạn có nghĩa là "cây".
grepnên làm. Nếu người dùng có các vòng lặp liên kết tượng trưng trong cấu trúc thư mục của họ, thì đó là vấn đề của người dùng :-)
/sys/devices/cpu/subsystem/devices/cpu/subsystem/devices/cpu/...(-XI như các công cụ chăm sóc tôi (trừ khi họ cung cấp ma thuật kỳ lạ mà họ gọi là "AI"). (-;
Như đã lưu ý ở trên -rhoặc -R(tùy thuộc vào xử lý symlink mong muốn) là một tùy chọn nhanh.
Tuy nhiên đôi khi -d <action>có thể hữu ích.
Điều thú vị -dlà lệnh bỏ qua, làm im lặng "grep: library_name: Is a library" khi bạn chỉ muốn quét mức hiện tại.
$ grep foo *
grep: q2: Is a directory
grep: rt: Is a directory
$ grep -d skip foo *
$
và tất nhiên:
$ grep -d recurse foo *
(list of results that don't exist because the word foo isn't in our source code
and I wouldn't publish it anyway).
$
Các -d skiptùy chọn là REALLY tiện dụng bên trong kịch bản khác, do đó bạn không cần phải 2> /dev/null. :)
Nếu bạn đang xử lý nhiều tệp, grep sẽ chạy nhanh hơn nếu bạn cắt bớt các tệp mà nó cần tìm kiếm thay vì lấy tất cả các tệp trong các thư mục con.
Đôi khi tôi sử dụng định dạng này:
grep "primary" `find . | grep cpp$`
Tìm tất cả các tập tin trong các thư mục con của .kết thúc đó cpp. Sau đó grep những tập tin cho "chính".
Nếu bạn muốn, bạn có thể tiếp tục chuyển các kết quả đó thành các cuộc gọi grep tiếp theo:
grep "primary" `find . | grep cpp$` | grep -v "ignoreThis" | grep -i "caseInsensitiveGrep"