「検索」は条件付きディープ検索を実行できません。

「検索」は条件付きディープ検索を実行できません。


見つかったコンテンツが現在のディレクトリにある場合、Findは条件付きディープ検索を実行しようとします。ファイルを見つけて、その出力を言語として解釈し、それ以外の場合は通常どおりに出力します。

$ find ~+ -maxdepth 1 \( -type f -printf 'File: %p\n' -o  -printf '%p\n' \) -o -mindepth 2 -printf '%p\n'

find: warning: you have specified the -mindepth option after a non-option argument (, but options are not positional (-mindepth affects tests specified before it as well as those specified after it)..

なぜ失敗し、そのような要件を解決するには?

ベストアンサー1

-maxdepth/ -mindepth(非標準のGNU拡張ですが、現在はfind他の多くの実装でサポートされています)はそうではありません。状況ディレクトリへの降り方に影響を与えるグローバルフラグである述語find

-maxdepth標準効果は次の組み合わせで達成できます。-path-prune

FreeBSDfind-depth n/-n/+深さn/ < />のnファイルは一致する必要があるため、nFreeBSDまたは派生製品(macOS、DragonFly BSD ...)では次のようになります。

find ~+ -depth 1 -type f -exec printf 'File: %s' {} ';' -o -print

ここでは-exec printfGNU固有の-printf

技術的にはprintf失敗する可能性があるため、オーバーライドを-print使用するとこの問題を解決できますが、表示順序に影響します。または、次のように変更できます。-exec ... {} +-exec ... {} ';'

find ~+ -depth 1 -type f '(' -exec printf 'File: %s' {} ';' -o -true ')' -o -print

または:

find ~+ '(' ! -depth 1 -o ! -type f ')' -print -o -exec printf 'File: %s' {} ';'

標準的なケースでは、-pathこれを代わりに使用できます(それほど単純ではありませんが)。

LC_ALL=C find ~+/. -path '*/./*/*' -print -o \
  -type f -printf 'File: %p\n' -o -print

または、深さを2に制限します(私の以前のバージョンの答えと同じようにあなたがそうであると-mindepth 2仮定します-maxdepth 2)。

LC_ALL=C find ~+/. -path '*/./*/*' -prune -print -o \
  -type f -printf 'File: %p\n' -o -print

(まだGNUに特化した標準ではありません-printf。)

sの深さ0点を示すために/.パスに追加します(そうでなければ$PWD/に表示されないことを保証します)。~+find-path

代わりに使用できません-path "$PWD/*/*"(例:提案された修正$PWD)これは、ワイルドカードまたはバックスラッシュを含む値では正しく機能しないためです(引数が-pathワイルドカードパターンとして扱われるため)。

比較する:

$ mkdir -p '[1]/2/3/4'
$ touch '[1]/2/3/4/file'
$ cd '[1]'
$ LC_ALL=C find ~+ -path "$PWD/*/*" -print -o -type f -printf 'File: %p\n' -o -print
/tmp/[1]
/tmp/[1]/2
/tmp/[1]/2/3
/tmp/[1]/2/3/4
File: /tmp/[1]/2/3/4/file
$ LC_ALL=C find ~+/. -path '*/./*/*' -print -o -type f -printf 'File: %p\n' -o -print
/tmp/[1]/.
/tmp/[1]/./2
/tmp/[1]/./2/3
/tmp/[1]/./2/3/4
/tmp/[1]/./2/3/4/file

代替案は追加することです。ただし、一部の実装では追加の後続ビットが削除される//ため、移植性が低下します。find/

パイプを介して出力から該当する項目をsed 's:/\./:/:'削除できます。/./

LC_ALL=CGNUはこれを必要とし、有効な文字を形成しないバイトシーケンスを含むパスコンポーネントを一致させるfindことはできません。*


GNUにはfindファイルの深さを明示的に一致させる述語はありませんが、その述語-printf印刷その深さ。したがって、ここではFile: 深さ1の一般ファイルに対応するプレフィックスを追加し、いくつかの後処理を実行できます。

find . -printf '%d%y,%p\0' | # print depth, type and path
  sed -z 's/^1f,/&File: /' | # add "File: " prefix for regulars at depth 1  
  cut -zd, -f2-            | # remove the depth and type
  tr '\0' '\n'               # NL delimited for user consumption

おすすめ記事