Avec GNU, ou FreeBSD ou NetBSD ou OpenBSD (et éventuellement d'autres) awk:
find . -type f -exec awk '
/^#!.*python/{print FILENAME}
{nextfile}' {} +
Ne regarderait que la première ligne de chaque fichier et exécuterait aussi peu awkque nécessaire.
La nextfiledéclaration ci-dessus n'est pas standard mais se trouve dans quelques implémentations, y compris GNU (qui est probablement d'où elle provient).
Bien que le code ci-dessus semble également fonctionner dans d'autres implémentations, l' nextfileinstruction n'y ferait rien (serait reconnue comme une expression consistant en une nextfilevariable non définie ), ce qui signifierait que tous les fichiers seraient lus entièrement et que le nom de fichier serait être imprimé pour chaque ligne correspondante.
Si vos awksupports FNR(comme les awks POSIX le font mais pas l'original awk, donc Solaris /usr/xpg4/bin/awket non /usr/bin/awk) et non nextfile, vous pouvez l'écrire:
find . -type f -exec awk 'FNR == 1 && /^#!.*python/{print FILENAME}' {} +
Ce qui fonctionnerait toujours aussi peu awkque possible mais lirait complètement les fichiers.
Une autre alternative pour éviter de lire les fichiers en entier et qui fonctionnerait avec tous awket findqui signifierait en exécuter un awkpar fichier serait:
find . -type f -exec awk '
/^#!.*python/{r=1};{exit}
END {exit(1-r)}' {} \; -print
grep -ls'il arrête de lire un fichier dès qu'il trouve une correspondance, pour les fichiers sans correspondance, il lit l'intégralité du fichier. Il trouverait également des correspondances au milieu des fichiers, donc par exemple, il pourrait correspondre à unsharfichier contenant des scripts python.