Đối với hồ sơ, đây là cách tiếp cận mà tôi thích:
grep pattern $(find . -type f ! -path './test/main.cpp')
Bằng cách giữ nguyên grepở đầu lệnh, tôi nghĩ rằng điều này rõ ràng hơn một chút - cộng với việc nó không tắt tính năng greptô sáng màu. Theo một nghĩa nào đó, sử dụng findthay thế lệnh chỉ là một cách để mở rộng / thay thế tập hợp tìm kiếm tệp (giới hạn) grepcủa chức năng.
Đối với tôi, find -execcú pháp là loại phức tạp. Một phức tạp vớifind -exec là (đôi khi) cần phải thoát khỏi các ký tự khác nhau (đáng chú ý là nếu \;được sử dụng theo Bash). Chỉ với mục đích đưa mọi thứ vào bối cảnh quen thuộc, hai lệnh sau về cơ bản là tương đương:
find . ! -path ./test/main.cpp -type f -exec grep pattern {} +
find . ! -path ./test/main.cpp -type f -print0 |xargs -0 grep pattern
Nếu bạn muốn loại trừ các thư mục con , có thể cần phải sử dụng ký tự đại diện. Tôi không hiểu đầy đủ về lược đồ ở đây - nói về phức tạp :
grep pattern $(find . -type f ! -path './test/main.cpp' ! -path './lib/*' )
Một lưu ý nữa để khái quát hóa findcác giải pháp dựa trên sử dụng trong các tập lệnh : Dòng greplệnh nên bao gồm -H/--with-filename tùy chọn . Nếu không, nó sẽ thay đổi định dạng đầu ra trong trường hợp chỉ có một tên tệp trong kết quả tìm kiếm từ đó find. Điều này là đáng chú ý bởi vì nó dường như không cần thiết nếu sử dụng greptìm kiếm tệp gốc (với -rtùy chọn).
... Mặc dù tốt hơn, là bao gồm /dev/null như một tệp đầu tiên để tìm kiếm. Điều này giải quyết hai vấn đề:
- Nó đảm bảo rằng nếu có một tệp để tìm kiếm,
grepsẽ nghĩ có hai tệp và sử dụng chế độ đầu ra nhiều tệp.
- Nó đảm bảo rằng nếu không có tệp để tìm kiếm,
grep sẽ nghĩ rằng có một tệp và không bị treo chờ trên stdin.
Vì vậy, câu trả lời cuối cùng là:
grep pattern /dev/null $(find . -type f ! -path './test/main.cpp')
--exclude-dir). Đó là lý do tại sao tôi muốn làm cho grep thực hiện loại trừ nguyên bản.