Для запису ось такий підхід, який я віддаю перевагу:
grep pattern $(find . -type f ! -path './test/main.cpp')
Зберігаючи grepна початку команди, я думаю, що це трохи зрозуміліше - плюс це не вимикає grepкольорове виділення. У певному сенсі використання findв підстановці команд - це лише спосіб розширення / заміни (обмеженого) підмножини пошуку файлів grep.
Для мене find -execсинтаксис є своєрідним таємничим. Однією із складнощів find -execє (іноді) потреба в уникненні різних символів (особливо, якщо \;використовується під Bash). Наступні дві команди є лише еквівалентними для цілей уведення звичних контекстів:
find . ! -path ./test/main.cpp -type f -exec grep pattern {} +
find . ! -path ./test/main.cpp -type f -print0 |xargs -0 grep pattern
Якщо ви хочете виключити підкаталоги , можливо, буде потрібно використовувати підстановку. Я не повністю розумію схему тут - поговоріть про таємницю :
grep pattern $(find . -type f ! -path './test/main.cpp' ! -path './lib/*' )
Ще одна примітка для узагальнення findрішень на основі базування для використання в скриптах : grepКомандний рядок повинен містити -H/ --with-filenameпараметр. Інакше це змінить формат виводу за умови, що в результатах пошуку буде лише одне ім'я файлу find. Це помітно, оскільки він, здається, не потрібен, якщо використовується grepвласний пошук файлів (з -rопцією).
... Ще краще - включити /dev/nullяк перший файл для пошуку. Це вирішує дві проблеми:
- Це гарантує, що якщо є один файл для пошуку,
grepподумає, що є два, і використовувати режим виводу з декількома файлами.
- Він гарантує, що якщо файлів для пошуку не
grepбуде , буде думати, що є один файл, і не зачекає на stdin.
Отже, остаточна відповідь:
grep pattern /dev/null $(find . -type f ! -path './test/main.cpp')
--exclude-dir). Ось чому я хотів би змусити греп виконувати виключення на місцях.