W przypadku GNU, FreeBSD lub NetBSD lub OpenBSD (i potencjalnie innych) awk
:
find . -type f -exec awk '
/^#!.*python/{print FILENAME}
{nextfile}' {} +
Spojrzałby tylko na pierwszą linię każdego pliku i uruchomiłby tak mało awk
s, jak to konieczne.
Powyższe nextfile
stwierdzenie nie jest standardowe, ale można je znaleźć w kilku implementacjach, w tym w GNU (prawdopodobnie z tego, skąd pochodzi).
Chociaż powyższy kod wydaje się działać również w innych implementacjach, nextfile
instrukcja nic by tam nie zrobiła (byłaby rozpoznawana jako wyrażenie składające się z nextfile
zmiennej nieustawionej ), co oznaczałoby, że wszystkie pliki zostałyby odczytane w całości, a nazwa pliku być drukowane dla każdej pasującej linii.
Jeśli twoje awk
wsparcie FNR
(takie jak POSIX-owe wersje robią, ale nie oryginalne awk
, więc w Solarisie /usr/xpg4/bin/awk
i nie /usr/bin/awk
) i nie nextfile
, możesz to napisać:
find . -type f -exec awk 'FNR == 1 && /^#!.*python/{print FILENAME}' {} +
Co nadal działałoby tak mało awk
jak to możliwe, ale w pełni odczytywało pliki.
Inną alternatywą, aby uniknąć czytania plików całkowicie i że będzie współpracować z każdym awk
, a find
jednak oznaczałoby uruchomiony jeden awk
na plik będzie:
find . -type f -exec awk '
/^#!.*python/{r=1};{exit}
END {exit(1-r)}' {} \; -print
grep -l
przestanie czytać plik, gdy tylko znajdzie dopasowanie, w przypadku plików bez dopasowania, odczyta cały plik. Znajduje również dopasowania w środku plików, więc na przykład może pasować doshar
pliku zawierającego skrypty python.