Đố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 grep
tô sáng màu. Theo một nghĩa nào đó, sử dụng find
thay 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) grep
của chức năng.
Đối với tôi, find -exec
cú 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 find
các giải pháp dựa trên sử dụng trong các tập lệnh : Dòng grep
lệ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 grep
tìm kiếm tệp gốc (với -r
tù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,
grep
sẽ 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.