Рекурсивный grep, совместимый с POSIX, без ошибок для недоступных каталогов

Какой скрипт позволит мне grep ключевое слово и напечатать имя файла, содержащее ключевое слово внутри содержимого файла, например «Carhart» внутри всех .sas-файлов во всех подкаталогах? Я пробовал что-то вроде следующего, но это не работает:

(find . -name '*.sas' -prune -type f -exec grep 'Carhart' > /dev/tty) >& /dev/null 

Сценарий удовлетворяет двум условиям

  1. Он работает на tcsh в Solaris на SPARC-Enterprise, который сертифицирован POSIX
  2. Он не генерирует строки «Разрешения на отказ» в каталогах, на которые у меня нет разрешения на поиск и / или чтение. (find / -name '* .sas' -prune> / dev / tty)> & / dev / null

Поскольку ( find / -name '*.sas' -prune > /dev/tty ) > & /dev/null работает без разрешения на отказ в разрешении, как я могу изменить эту простую строку, чтобы включить grep?

Чтобы grep печатал только имя файла, передайте параметр -l . Чтобы найти подстроку, а не регулярное выражение, перейдите в опцию -F .

Чтобы рекурсивно искать файлы, чье имя соответствует определенному шаблону, используйте find с параметрами -type f и -name PATTERN . Используйте -exec для вызова grep.

 find . -name '*.sas' -type f -exec grep -F -l 'Carhart' {} + 

Если вы хотите избежать ошибок в каталогах, которые вам не разрешены, вы можете использовать -perm , -perm и -group для анализа разрешений (что трудно получить правильно и не будет работать, если у вас есть ACL) , или test вызова (который замедляется, потому что это внешняя программа, но более надежная).

 find . -type d ! -exec test -r {} -a -x {} \; -prune -o \ -name '*.sas' -type f -exec test -r {} \; -exec grep -F -l 'Carhart' {} +