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 awk
que nécessaire.
La nextfile
dé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' nextfile
instruction n'y ferait rien (serait reconnue comme une expression consistant en une nextfile
variable 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 awk
supports FNR
(comme les awks POSIX le font mais pas l'original awk
, donc Solaris /usr/xpg4/bin/awk
et 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 awk
que possible mais lirait complètement les fichiers.
Une autre alternative pour éviter de lire les fichiers en entier et qui fonctionnerait avec tous awk
et find
qui signifierait en exécuter un awk
par fichier serait:
find . -type f -exec awk '
/^#!.*python/{r=1};{exit}
END {exit(1-r)}' {} \; -print
grep -l
s'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 à unshar
fichier contenant des scripts python.