パターンに一致するファイルを含むディレクトリを探しています。たとえば、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*.csv
zshはサブディレクトリを見つけるためにすべての(隠されていない)ディレクトリの内容全体を読み取る必要があります。
答え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"
' {} ';'
上記のコマンドについて。
-prune
find
標準と同様に、find
サブディレクトリへのダウンはブロックされます。 AFAICT、GNUフレーバー、またはNetBSDフレーバーはsfind
ありませんが、関数内の被呼者から呼び出すと同じ効果が得られ、より柔軟になります。-quit
-exec [status]
return
-call[dir]
答え4
代わりにfind
sオプションを使用してください。-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検索の両方で使用できます。