@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
任意のパス引数をサポートできないという事実を回避するためです(-f
FreeBSD を除くfind
)$dir
like !
または-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
ます(ただし、上記の無効な文字に関する問題に注意してください)。-true
find
-links +0
-name '*'
-depth -2
、-depth 1
...アプローチは、GNUのより良いとして見ることができる-maxdepth
/-mindepth