@meuhのアプローチは非効率的です。なぜなら、彼の-maxdepth 1アプローチfindではレベル1のディレクトリの内容を読み取って、それ以外の場合は後で無視できるからです。一部のディレクトリ名に、ユーザーのロケールで有効な文字を形成しないバイトシーケンスが含まれている場合(別の文字エンコーディングのファイル名findなどfind)、一部の実装(GNUを含む)でも正常に動作しません。
find . \( -name . -o -prune \) -extra-conditions-and-actions
GNU -maxdepth 1(またはFreeBSD -depth -2)を実装する、より標準的な方法です。
ただし、一般的には、考慮したくない(深さ0)ために-depth 1(-mindepth 1 -maxdepth 1)が必要.であり、さらに簡単です:
find . ! -name . -prune -extra-conditions-and-actions
の場合-maxdepth 2、次のようになります。
find . \( ! -path './*/*' -o -prune \) -extra-conditions-and-actions
そして、それはあなたが無効なキャラクターの問題で実行する場所です。
たとえば、あなたはというディレクトリがある場合Stéphaneが、é西ヨーロッパとアメリカで最も一般的なアップは、その後0xe9バイトがないことを、半ば2000年代まであったように、ISO8859-1(別名latin1の)文字セット(0xe9バイト)でエンコードされているがUTF-8の有効な文字。だから、UTF-8ロケールでは、*(一部でワイルドカードfindの実装が)一致しませんStéphaneよう*0以上で、文字と文字が0xe9ではありません。
$ locale charmap
UTF-8
$ find . -maxdepth 2
.
./St?phane
./St?phane/Chazelas
./Stéphane
./Stéphane/Chazelas
./John
./John/Smith
$ find . \( ! -path './*/*' -o -prune \)
.
./St?phane
./St?phane/Chazelas
./St?phane/Chazelas/age
./St?phane/Chazelas/gender
./St?phane/Chazelas/address
./Stéphane
./Stéphane/Chazelas
./John
./John/Smith
My find(出力が端末に送信されるとき)は、?上記のように無効な0xe9バイトを表示します。d でSt<0xe9>phane/Chazelasはないことがわかりpruneます。
次の方法で回避できます。
LC_ALL=C find . \( ! -path './*/*' -o -prune \) -extra-conditions-and-actions
ただし、それはすべてのロケール設定findとそれが実行するアプリケーションに影響することに注意してください(-exec述語経由など)。
$ LC_ALL=C find . \( ! -path './*/*' -o -prune \)
.
./St?phane
./St?phane/Chazelas
./St??phane
./St??phane/Chazelas
./John
./John/Smith
今、私は本当に得ます-maxdepth 2が、UTF-8で適切にエンコードされた2番目のステファンのéは、éのUTF-8 ??エンコーディングの0xc3 0xa9バイト(Cロケールでは2つの個別の未定義文字と見なされます)として表示されることに注意してくださいCロケールでは印刷できない文字。
を追加した場合-name '????????'、間違ったステファン(iso8859-1でエンコードされたもの)を取得していたでしょう。
の代わりに任意のパスに適用するには.、次のようにします。
find some/dir/. ! -name . -prune ...
以下のため-mindepth 1 -maxdepth 1か:
find some/dir/. \( ! -path '*/./*/*' -o -prune \) ...
のために-maxdepth 2。
私はまだやる:
(cd -P -- "$dir" && find . ...)
まず、パスが短くなり、パスが長すぎる問題や引数リストが長すぎる問題に陥る可能性が低くなりますが、find任意のパス引数をサポートできないという事実を回避するためです(-fFreeBSD を除くfind)$dirlike !または-print...の値
-o否定との組み合わせでは、の2つの独立したセットを実行するための一般的なトリックである-condition/を-actionにfind。
-action1ファイル会議で実行し、ファイル会議-condition1で独立-action2して実行する場合-condition2、次の操作はできません。
find . -condition1 -action1 -condition2 -action2
-action2唯一満たすファイルに対して実行されます両方の条件を。
また:
find . -contition1 -action1 -o -condition2 -action2
-action2一致するファイルのために実行されないの両方の条件を。
find . \( ! -condition1 -o -action1 \) -condition2 -action2
働く\( ! -condition1 -o -action1 \)に解決だろう真のすべてのファイルのために。それは想定して-action1(のようなアクションで-prune、-exec ... {} +常に返すこと)真。そのようなアクション-exec ... \;がfalseを返す可能性がある場合、GNU またはorの ように無害であるがtrueを返す別の-o -something場所を追加することができ-somethingます(ただし、上記の無効な文字に関する問題に注意してください)。-truefind-links +0-name '*'
-depth -2、-depth 1...アプローチは、GNUのより良いとして見ることができる-maxdepth/-mindepth