Finde alle Dateien mit einem Python Shebang

9

Ich versuche, eine PEP8-Prüfung für einen großen Quellbaum durchzuführen. Der Baum besteht aus einer Mischung von Dateien in verschiedenen Sprachen. Die Idee ist, alle Python-Skripte zu überprüfen, ohne sie explizit auflisten zu müssen. Die meisten dieser Dateien haben keine .pyErweiterung. Gibt es eine einfache Möglichkeit, alle Dateien mit dem Wort Python im Shebang zu finden oder alle Dateien zu finden, die bei der Ausführung mit Python ausgeführt würden?

Marco Ceppi
quelle

Antworten:

7

Versuchen Sie Folgendes:

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

Gleiches gilt für ack :

ack -rl '^#!/.*python' .
Gilles Quenot
quelle
5
Beachten Sie, dass beim grep -lLesen einer Datei zwar keine Übereinstimmung gefunden wird, bei Dateien ohne Übereinstimmung jedoch die gesamte Datei gelesen wird. Es würde auch Übereinstimmungen in der Mitte von Dateien finden, so dass es beispielsweise mit einer sharDatei übereinstimmen könnte , die Python-Skripte enthält.
Stéphane Chazelas
14

Mit GNU oder FreeBSD oder NetBSD oder OpenBSD (und möglicherweise anderen) awk:

find . -type f -exec awk '
  /^#!.*python/{print FILENAME}
  {nextfile}' {} +

Würde nur in die erste Zeile jeder Datei schauen und so wenig awks wie nötig ausführen .

Die nextfileobige Aussage ist kein Standard, findet sich jedoch in einigen Implementierungen, einschließlich der GNU (von der sie wahrscheinlich stammt).

Während der obige Code auch in anderen Implementierungen zu funktionieren scheint, würde die nextfileAnweisung dort nichts tun (würde als Ausdruck erkannt werden, der aus einer nicht gesetzten nextfileVariablen besteht), was bedeuten würde, dass alle Dateien vollständig gelesen würden und der Dateiname würde für jede passende Zeile gedruckt werden.

Wenn Ihre awkUnterstützung FNR(wie POSIX awks, aber nicht das Original awk, also unter Solaris /usr/xpg4/bin/awkund nicht /usr/bin/awk) und nicht nextfile, können Sie es schreiben:

find . -type f -exec awk 'FNR == 1 && /^#!.*python/{print FILENAME}' {} +

Was immer noch so wenig awks wie möglich laufen würde, aber die Dateien vollständig lesen würde.

Eine weitere Alternative zu vermeiden , dass die Dateien vollständig zu lesen und das würde mit jedem arbeiten awkund findaber würde bedeuten , läuft eine awkpro Datei wäre:

find . -type f -exec awk '
  /^#!.*python/{r=1};{exit}
  END {exit(1-r)}' {} \; -print
Stéphane Chazelas
quelle
1
+1, aber der letzte Befehl stimmt auch mit leeren Dateien überein.
10.
Guter Punkt @ l0b0. Aktualisiert.
Stéphane Chazelas