С GNU, FreeBSD, NetBSD или OpenBSD (и, возможно, другими) awk:
find . -type f -exec awk '
/^#!.*python/{print FILENAME}
{nextfile}' {} +
Будет смотреть только на первую строку каждого файла и будет запускать столько, awkсколько необходимо.
nextfileВыше утверждение не является стандартным , но находится в нескольких реализациях , включая GNU один (который, вероятно , где она возникла из).
Хотя приведенный выше код, по-видимому, будет работать и в других реализациях, nextfileоператор не будет ничего делать там (будет распознаваться как выражение, состоящее из неустановленной nextfileпеременной), так что это будет означать, что все файлы будут прочитаны полностью, а имя файла будет быть напечатан для каждой соответствующей строки.
Если вы awkподдерживаете FNR(как в POSIX awks, но не в оригинале awk, а в Solaris /usr/xpg4/bin/awkнет /usr/bin/awk) nextfile, вы можете написать:
find . -type f -exec awk 'FNR == 1 && /^#!.*python/{print FILENAME}' {} +
Который по-прежнему будет работать как awkможно меньше, но будет читать файлы полностью.
Другой вариант , чтобы избежать полного чтения файлов и что будет работать с каждым awkи , findно будет означать , работает один awkна один файл будет выглядеть так :
find . -type f -exec awk '
/^#!.*python/{r=1};{exit}
END {exit(1-r)}' {} \; -print
grep -lон остановит чтение файла, как только найдет совпадение, для файлов без совпадения он прочитает весь файл. Он также будет находить совпадения в середине файлов, например, он может совпадать сsharфайлом, содержащим скрипты Python.