Trova tutti i file con un Python Shebang


9

Sto cercando di eseguire un controllo PEP8 su un grande albero dei sorgenti. L'albero è composto da un mix di file in varie lingue. L'idea è di controllare tutti gli script Python senza doverli elencare esplicitamente. La maggior parte di questi file non ha in realtà .pyun'estensione. C'è un modo semplice per trovare tutti i file con la parola Python nello shebang o trovare tutti i file che verrebbero eseguiti con Python quando eseguiti?

Risposte:


7

Prova a fare questo:

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

Stessa cosa con ack :

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

5
Si noti che mentre grep -lsmetterebbe di leggere un file non appena trova una corrispondenza, per i file senza corrispondenza, leggerebbe l'intero file. Troverebbe anche corrispondenze nel mezzo di file, quindi ad esempio potrebbe corrispondere su un sharfile che contiene script Python.
Stéphane Chazelas,

14

Con GNU o FreeBSD o NetBSD o OpenBSD (e potenzialmente altri) awk:

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

Guarderebbe solo la prima riga di ogni file e eseguirà il numero di awksecondi necessario.

L' nextfileaffermazione sopra non è standard ma si trova in alcune implementazioni tra cui quella GNU (che è probabilmente la sua origine).

Mentre il codice sopra sembra funzionare anche in altre implementazioni, l' nextfileistruzione non farebbe nulla lì (sarebbe riconosciuta come un'espressione consistente in una nextfilevariabile non impostata ), quindi ciò significherebbe che tutti i file verrebbero letti completamente e il nome file essere stampato per ogni riga corrispondente.

Se i tuoi awksupporti FNR(come fanno i awks POSIX ma non l'originale awk, quindi su Solaris /usr/xpg4/bin/awke non /usr/bin/awk) e non nextfile, puoi scriverli:

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

Che avrebbe comunque eseguito il minor numero di awksecondi possibile ma avrebbe letto completamente i file.

Un'altra alternativa per evitare di leggere i file completamente e che funzionerebbe con tutti awke findche significherebbe eseguirne uno awkper file sarebbe:

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

1
+1, ma l'ultimo comando corrisponde anche a file vuoti.
l0b0,

Buon punto @ l0b0. Aggiornato.
Stéphane Chazelas,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.