ワイルドカードを使用した find -exec

ワイルドカードを使用した find -exec

私は、bash の「find」を使用して、.log ファイルを含むすべてのフォルダーを処理し、そのサイズを取得しようとしています。しかし、ワイルドカードは期待どおりに機能しません。何も返されません。

find . -type d -exec test -e '{}/*.log' \; -exec du -d0 '{}' \;

*.logただし、を に置き換えるとfoo.log、そのファイル名を含むディレクトリに対して期待どおりに動作します。

いくつかの同様の SE 投稿に基づいて、次のことを試しました。

find . -type d -exec bash -c 'test -e "{}/*.log"' \; -exec du -d0 '{}' \;
find . -type d -exec bash -c 'test -e "$1/*.log"' '{}' \; -exec du -d0 '{}' \;

しかし、それらはそれほどうまく機能しません。

答え1

のようfind … -exec test -e '{}/*.log'な文字列を に渡すと、something/*.logtest*リテラルどちらのツールもこれをワイルドカードとして扱いません。 の実装によっては、これが引数の一部である場合(引数全体ではなく)findも展開されません。{}{}

後で試すものの 1 つは、{}シェル コードに埋め込まれます。{}シェルコードに埋め込まないこの問題に関しては、もう1つの試みの方が良いでしょう。解決に近づいています。ちょっと仕事:

# still flawed though
find . -type d -exec bash -c 'test -e "$1/"*.log' bash '{}' \; -exec du -d0 '{}' \;

見るの2番目のshは何ですかsh -c 'some shell code' sh?ただし、主な「修正」は、シェル コードでアスタリスクを引用符で囲まないことです。この方法では、内部シェルではワイルドカードになります (ただし、外部シェルではワイルドカードにならず、適切に単一引用符で囲まれます)。問題は、*.log複数の単語に展開される可能性があることです (一致するファイルが多数ある場合)。この場合、test呼び出しが中断されます。

次のコードは*.logファイルのあるディレクトリを検索します。

find . -type d -exec sh -c '
   for f in "$1/"*.log; do test -e "$f" && exit 0; done; exit 1
' sh {} \; -print

このコードは移植可能です。 inner は必要なくbashshより高速になるはずです。必要に応じ-printて に置き換えてください。-exec du …

exit 0これは、一致するファイル¹の存在が確認されるとすぐに、内部シェルから成功 ( ) を返すことによって機能しますtest。まだテストされていない一致するファイル (存在する場合) は無駄にテストされず、これにより時間が節約されます。一致しない場合は、パターンはリテラルのままで失敗testし、シェル全体が失敗して終了します ( exit 1)。-execもテストであるため、-print(または-exec du …そこに置いたもの) が実行されるかどうかに影響することに注意してください。


別のアプローチとしては、find一致するファイルを見つけるようにする

find . -name '*.log' … -print

そして、その出力を解析してディレクトリ名を分離し、最終的に で使用しますxargsduディレクトリは複数回出現する可能性があり、パス名内の改行には移植性のないコード ( から始まる) が必要になります-print0。これは不必要に複雑になると思います。ディレクトリを検索する方が優れているようです。


¹test -eファイルがあるかどうかはメモで確認できますディレクトリなど通常のファイルの存在を確認するには を使用しますtest -f

答え2

ログ ファイルを検索/スキャンして、一意のディレクトリ名を収集する方が簡単になります。

このfindコマンドは、ディレクトリを抽出し、uniq重複を削除して追加します。/フラグは、改行/スペース/引用符を含むパス名が完璧に解析されるようにするのに役立ちます-z-0

find . -type f -name \*.log -exec dirname -z {} \+ | uniq -z | xargs -0 -r du -d0

| sort -rn |head最大のディスク使用量を検索する場合に追加します。

関連情報