Найти все файлы с Python Shebang

9

Я пытаюсь запустить проверку PEP8 для большого дерева исходных текстов. Дерево состоит из смеси файлов на разных языках. Идея состоит в том, чтобы проверить все скрипты Python без явного перечисления их. Большинство этих файлов на самом деле не имеют .pyрасширения. Есть ли простой способ найти все файлы со словом Python в shebang или найти все файлы, которые будут запускаться с Python при запуске?

Марко Чеппи
источник

Ответы:

7

Попробуйте сделать это:

grep -rl '^#!/.*python' .

То же самое с Ack :

ack -rl '^#!/.*python' .
Жиль Квено
источник
5
Обратите внимание, что, хотя grep -lон остановит чтение файла, как только найдет совпадение, для файлов без совпадения он прочитает весь файл. Он также будет находить совпадения в середине файлов, например, он может совпадать с sharфайлом, содержащим скрипты Python.
Стефан Шазелас
14

С 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
Стефан Шазелас
источник
1
+1, но последняя команда также соответствует пустым файлам.
10
Хороший вопрос @ l0b0. Обновлено.
Стефан Шазелас