回答:
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
が、1つの実行中を意味しますawk
ファイルごとに次のようになります。
find . -type f -exec awk '
/^#!.*python/{r=1};{exit}
END {exit(1-r)}' {} \; -print
grep -l
にはマッチしないとファイルのために、一致するものを見つけるとすぐにファイルの読み取りを停止だろう、それはファイル全体を読んでいました。また、ファイルの途中で一致を見つけるため、たとえば、shar
pythonスクリプトを含むファイルで一致する可能性があります。