Câu trả lời:
Chà, trường hợp chung hoạt động với bất kỳ lệnh nào ghi vào thiết bị xuất chuẩn là sử dụng xargs
, điều này sẽ cho phép bạn đính kèm bất kỳ số lượng đối số dòng lệnh nào vào cuối lệnh:
$ find … | xargs grep 'search'
Hoặc để nhúng lệnh trong grep
dòng của bạn bằng backticks hoặc $()
, nó sẽ chạy lệnh và thay thế đầu ra của nó:
$ grep 'search' $(find …)
Lưu ý rằng các lệnh này không hoạt động nếu tên tệp chứa khoảng trắng hoặc một số ký tự kỳ lạ khác của Wikipedia ( \'"
đối với xargs, \[*?
for $(find …)
).
Tuy nhiên, trong trường hợp cụ thể find
, khả năng thực thi chương trình trên các đối số đã cho được tích hợp sẵn:
$ find … -exec grep 'search' {} \;
Tất cả mọi thứ giữa -exec
và ;
là lệnh để thực thi; {}
được thay thế bằng tên tệp được tìm thấy bởi find
. Điều đó sẽ thực thi riêng grep
cho từng tệp; vì grep
có thể lấy nhiều tên tệp và tìm kiếm tất cả, bạn có thể thay đổi thành ;
để +
tìm tìm để chuyển tất cả tên tệp phù hợp thành grep
cùng một lúc:
$ find … -exec grep 'search' {} \+
find ... -type f -print0 | xargs -r0 grep 'search' /dev/null
. QED. Mặc dù -exec +
rất hiệu quả, nó không tồn tại trên tất cả các phiên bản tìm kiếm.
$ find … -exec grep 'search' {} \+
hình thức là nhiều nhanh nhất.
Một số phiên bản grep
(ví dụ: trên Linux hoặc BSD hoặc Mac OS X không nhúng ) có -r
tùy chọn để thực hiện tìm kiếm đệ quy. Trên OpenBSD, sử dụng -R
(và không có --exclude
như trong ví dụ bên dưới). Điều này bao gồm các kết hợp đơn giản find
với grep
.
Nếu việc triển khai của bạn không có -R
cờ hoặc nếu bạn muốn các tiêu chí khớp với tệp fancier, bạn có thể sử dụng -exec
chính find
để thực hiện nó grep
. Một vài cũ find
triển khai không hỗ trợ -exec
... +
; trên các hệ thống này, hãy sử dụng ;
thay vì +
(điều này sẽ gọi grep
một lần cho mỗi tệp, vì vậy nó sẽ chậm hơn, nhưng nếu không thì kết quả sẽ giống nhau). Lưu ý /dev/null
mẹo để gây ra grep
để hiển thị tên tệp ngay cả khi nó được gọi trên một tệp duy nhất (GNU grep và FreeBSD / NetBSD / OSX grep có -H
tùy chọn để đạt được hiệu ứng tương tự).
find . -type f -name '*.o' -prune -o -exec grep 'needle' /dev/null {} +
grep -r --exclude='*.o' 'needle' .
GNU grep
có -H
tùy chọn để luôn luôn in tên tệp.