Con GNU, o FreeBSD o NetBSD u OpenBSD (y potencialmente otros) awk:
find . -type f -exec awk '
/^#!.*python/{print FILENAME}
{nextfile}' {} +
Solo miraría la primera línea de cada archivo y correría tan pocos awkcomo sea necesario.
La nextfiledeclaración anterior no es estándar, pero se encuentra en algunas implementaciones, incluida la GNU (que probablemente es de donde se originó).
Si bien el código anterior también parece funcionar en otras implementaciones, la nextfiledeclaración no haría nada allí (se reconocería como una expresión que consiste en una nextfilevariable no establecida), por lo que eso significaría que todos los archivos se leerían completamente y el nombre de archivo sería Se imprimirá para cada línea coincidente.
Si sus awksoportes FNR(como POSIX awks lo hacen pero no el original awk, así que en Solaris /usr/xpg4/bin/awky no /usr/bin/awk) y no nextfile, puede escribirlo:
find . -type f -exec awk 'FNR == 1 && /^#!.*python/{print FILENAME}' {} +
Que aún se ejecutaría la menor cantidad de awksegundos posible, pero leería los archivos por completo.
Otra alternativa para evitar leer los archivos por completo y que funcionaría con todos awky findsignificaría ejecutar uno awkpor archivo sería:
find . -type f -exec awk '
/^#!.*python/{r=1};{exit}
END {exit(1-r)}' {} \; -print
grep -lbien dejaría de leer un archivo tan pronto como encuentre una coincidencia, para los archivos sin coincidencia, leería todo el archivo. También encontraría coincidencias en el medio de los archivos, por lo que, por ejemplo, podría coincidir en unshararchivo que contiene scripts de Python.