一致するファイルを含むすべてのディレクトリを検索するには?

一致するファイルを含むすべてのディレクトリを検索するには?

パターンに一致するファイルを含むディレクトリを探しています。たとえば、foobar*.csvこれらのファイルを含むディレクトリには数百を含めることができます。サブディレクトリなし! )、だからfindが見つかったらすぐに印刷してhere/is/the/path/to/dir下降here/is/the/path/to/dir/foobar-2022-01-01.csvを停止したいと思います。

どうすればいいですか?

答え1

find /path/to/base/dir -type f -name "foobar*.csv" -exec dirname {} \; | sort -u

説明する:

  • "foobar*.csv"パターンに一致するすべてのファイルを見つけます。
  • 各ファイルのディレクトリ名を取得します。
  • 一意に並べ替えます。

これはメモリを節約しませんが、「数百」のファイルの結果を取得するのに数ミリ秒かかります。

答え2

zshを使う:

dirs=( **/*(/e['()(($#)) $REPLY/foobar*.csv(NY1)']) )

一致するディレクトリのサブディレクトリを見つけようとし、最初の一致で停止するため、立ち下がりは停止されませY1んが、foobar*.csvzshはサブディレクトリを見つけるためにすべての(隠されていない)ディレクトリの内容全体を読み取る必要があります。

答え3

使用(POSIXに類似)boshシェル、これはfind(実際にsfind)が組み込まれており、シェルコードを評価できるいくつかの述語/条件があります-call-calldir

find_match() {
  find . ! -name . -prune -name "$1" -call 'pwd; return' ';'
  false
}
find . -type d -calldir 'find_match "foobar*.csv"' ';' -prune

一致するディレクトリに対して作業を実行するには、次を追加します。

-call '
  dir=$1
  whatever you need to do with "$dir"
' {} ';'

上記のコマンドについて。

-prunefind標準と同様に、findサブディレクトリへのダウンはブロックされます。 AFAICT、GNUフレーバー、またはNetBSDフレーバーはsfindありませんが、関数内の被呼者から呼び出すと同じ効果が得られ、より柔軟になります。-quit-exec [status]return-call[dir]

答え4

代わりにfindsオプションを使用してください。-execdir-exec

find . -iname 'foobar*.csv' -execdir sh -c 'pwd' {} +

これはファイル名引数が許可されず、与えられると文句を言うのでsh -cラッパーpwd(単に実行する代わりに-execdir pwd {} +)を使用します。pwdシェルラッパーを使用すると、ファイル名引数を渡さずにディレクトリから pwd を実行できます。

または、ディレクトリ内の一致するファイルの数がARG_MAXの数(Linuxでは約2 MBであるため、可能性が低い)を超える可能性がある場合は、出力をuniq

find . -iname 'foobar*.csv' -execdir sh -c 'pwd' {} + | uniq

注:-execdirこれはPOSIXコマンドの標準外の改善ですfind。一部のバージョンfind(特に古いバージョンおよび/または排他的なバージョン)では欠落している可能性があります。それはいGNU検索とBSD検索の両方で使用できます。

関連情報