Знайдіть усі файли за допомогою Python Shebang


9

Я намагаюся запустити перевірку PEP8 щодо великого дерева-джерела. Дерево складається з суміші файлів на різних мовах. Ідея полягає у тому, щоб перевірити всі сценарії Python, не маючи явного переліку їх. Більшість цих файлів насправді не мають .pyрозширення. Чи є простий спосіб знайти всі файли зі словом Python в шебангу або знайти всі файли, які запускалися б із Python при виконанні?

Відповіді:


7

Спробуйте зробити це:

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

Те ж саме з ack :

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

5
Зауважте, що хоча grep -lперестане читати файл, як тільки він знайде збіг, для файлів, які не відповідають, він би прочитав весь файл. Він також знайде збіги в середині файлів, так що, наприклад, він може відповідати sharфайлу, що містить сценарії python.
Stéphane Chazelas

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}' {} +

Який би ще працював якомога менше awks, але повністю читав би файли.

Інший варіант , щоб уникнути повного читання файлів і що буде працювати з кожним awkі , findале означатиме , працює один awkна один файл буде виглядати так :

find . -type f -exec awk '
  /^#!.*python/{r=1};{exit}
  END {exit(1-r)}' {} \; -print

1
+1, але остання команда також відповідає порожнім файлам.
l0b0

Хороша точка @ l0b0. Оновлено.
Стефан Шазелас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.