find コマンドから 1 つの特定のパスを除くすべてのサブディレクトリを除外

find コマンドから 1 つの特定のパスを除くすべてのサブディレクトリを除外

find特定のディレクトリパスを無視し、現在のサブディレクトリから特定の拡張子を持つすべてのファイルを検索するコマンドを使用します。

find -L . \( -wholename "*/ignoredPath" -o -wholename "*/ignoredPath2" \) -prune -o -name "*.ext"

これはうまくいきますが、今では正確なサブディレクトリの1つを除いて他のパスを無視したいと思います。無視するすべてのサブディレクトリを一覧表示せずにこれを行うにはどうすればよいですか?

たとえば、次のフォルダツリーがあるとします。

*/base/pathToIgnore1
*/base/subdir/requiredPath
*/base/subdir/pathToIgnore2
*/base/subdir/pathToIgnore3
*/base/pathToIgnore4

パスを除くすべてのサブディレクトリを無視findするコマンドを作成するにはどうすればよいですか?base*/base/subdir/requiredPath

私は次のことを試しました

find -L . \( -wholename "*/ignoredPath" -o -wholename "*/ignoredPath2" -o \( -wholename "*/base" -a ! -wholename "*/base/subdir/requiredPath" \) \) -prune -o -name "*.ext"

しかし、うまくいかず、すべてのbaseサブディレクトリは無視されます。

ベストアンサー1

find -L . \
  \( -type d \
    \( -path "*/ignore" -o -path "*/indeed" -o \
      \( -path "*/subdir/*" ! -path "*/subdir/save" \
      \) \
    \) \
  \) \
  -prune -o -print

追加のフィルタ(たとえば-name "*.ext")が必要な場合は、フィルタを前に配置する必要があります-print。最後の部分はこれです

  -prune -o \( -name "*.ext" \) -print

書きやすく読みやすいように名前を変更しました。で始まる名前はi無視されます。sで始まる名前が表示されます。で終わる名前はfileファイルです。

私の木は次のとおりです

$ find -printf "%y %p\n"
d .
d ./base
d ./base/subdir
d ./base/subdir/inform
f ./base/subdir/inform/imagefile
d ./base/subdir/isolate
f ./base/subdir/isolate/individualfile
f ./base/subdir/whatwhatinthefile
d ./base/subdir/save
f ./base/subdir/save/soundfile
f ./base/superfile
d ./base/indeed
f ./base/indeed/itemfile
d ./base/show
f ./base/show/startfile
d ./base/ignore
f ./base/ignore/importantfile

上記のコマンドの出力:

.
./base
./base/subdir
./base/subdir/whatwhatinthefile
./base/subdir/save
./base/subdir/save/soundfile
./base/superfile
./base/show
./base/show/startfile

whatwhatinthefilebase/subdirこれらのファイルを望まない場合は、明示的にbase/subdir除外する必要があります。試してみましたが、コマンドラインがとても見苦しくなりました。

ユースケースに応じて、次のようにシェル関数を定義する方が簡単です。

contrivedfind() {
  find -L . \
    \( -type d \
      \( -path "*/ignore" -o -path "*/indeed" -o -path "*/subdir" \
      \) \
    \) \
    -prune -o -print
  find -L ./base/subdir/save
}

これで出力は次のようになります。

.
./base
./base/superfile
./base/show
./base/show/startfile
./base/subdir/save
./base/subdir/save/soundfile

以前と唯一の違いは、./base/subdirアイテムがないことです。しかし、とにかくファイルをフィルタリングしたいので、それは重要ではないと思います。

前と同様に、-print最初のフィルタの前に追加のフィルタを配置する必要がありfind、今回は2番目のフィルタの最後に配置する必要がありますfind

おすすめ記事