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 grep
hỗ trợ -r
tù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!
grep
trê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-dir
thự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-dir
là độc quyền cho GNU grep
. (-:
Một câu trả lời tối ưu phụ: Thay vì dẫn đầu ra find
và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 grep
và ack
, -i
switch 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 --color
và các -n
cô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 -R
tù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 grep
triển khai.
-r
thay vì -R
bỏ qua các liên kết tượng trưng khi GNU grep có liên quan
grep
triể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".
grep
nê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 -r
hoặ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ị -d
là 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 skip
tù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"