コマンドの使い方に関するより良いアイデアを得るために、findに関するドキュメントを見つけました。
私が読んでいる部分はこう言います。
GNU find は、2 つの方法のいずれかでシンボリックリンクを処理します。まず、リンクを逆参照できます。つまり、シンボリックリンクを検出すると、リンクが指すファイルを調べて、指定した基準を満たしていることを確認します。次に、実際のリンクを探している場合は、リンク自体を確認できます。 findコマンドを使用して取得したディレクトリ階層内のファイルをシンボリックリンクが指す場合、2つの方法の間に大きな違いがない可能性があります。
デフォルトでは、findはシンボリックリンクを見つけたらそれ自体をチェックします(そして、後でリンクされたファイルが見つかるとリンクもチェックします)。
私が理解しているように、次のようなことをした場合:
find -L -iname "*foo*"
これは現在のディレクトリを再帰的に検索し、シンボリックリンクが見つかると元のファイルへのリンクに沿って検索します。元のファイル名がパターンの場合、前のリンクが*foo*
報告されます。
しかし、これは本当ではないようです。私は持っています
main-file
sl-file -> main-file
上記のコマンドを実行すると報告さfind -L -iname "*main*"
れます。
./main-file
楽しみにしています
./main-file # because it matches the criterion
./sl-file # because the file points to matches the criterion
つまり、別のテストを使用すると、期待-type
どおりに機能します。私がこれを持っているとしましょう:
main-file
dir/sl-file -> ../main-file
これを実行
find dir -type f
何も返しません。しかし、これは
find -L dir -type f
レポートdir/sl-file
。
何を提供しますか?
私はすでに経験したこの投稿これは、ファイル名がファイル属性ではないことを意味します。これは本当に理解できないことです。
答え1
Gnufind
文書は用語では似ていません。POSIXワン。後者は要点を説明し、私はそれに言及します。定義されていない-iname
ので、これに焦点を当てます。大文字と小文字を区別せずに同様に設計されていると-name
思います。したがって、私はそのすべての属性が適用可能なケースから独立していることを望みます。-iname
-name
-name
-iname
POSIX 文書の関連部分は次のとおりです。
find [-H|-L] path... [operand_expression...]
このユーティリティは[… ]で指定された各ファイルで、ディレクトリ階層を繰り返しダウンさせる必要がfind
あります。末尾の<スラッシュ>文字を含むpath
各path
オペランドは、指定されたとおりに評価されます。階層で見つかった他のファイルへのすべてのパス名は、現在のパスオペランド(現在のパスオペランドが1で終わらない場合は<スラッシュ>)として評価されます。パスオペランドに基づいてファイル名を連結します。反対の部分にはドットまたはドット - コンポーネントを含めないでください。末尾の<スラッシュ>文字も含めないでください。パス名コンポーネントの間には単一の<スラッシュ>文字のみを含める必要があります。
-name pattern
現在のパス名の基本名がパターンマッチング表記を使用して一致する場合、pattern
基本用語はtrueと評価する必要があります[...]
[...] 現在のパス名が標準出力に書き込まれます。
そして定義:
basename
1つ以上のファイル名を含むパス名の場合:パス名の最後または唯一のファイル名。 [… ]
ファイル名
ファイル名を指定するために使用される一連のバイト[...]。名前を構成するバイトには <NUL> または <slash> 文字を含めることはできません。 [...] ファイル名は「パス名コンポーネント」とも呼ばれます。 [… ]
パス名
ファイルを識別するために使用される文字列。 [...]オプションの開始<スラッシュ>文字が続き、その後に<スラッシュ>文字で区切られた0個以上のファイル名が続きます。
したがって、-name
現在のパス名の最終ファイル名に興味があります。現在のパス名は、現在のファイルを識別する文字列です。誰によって使用されますか?この場合、find
パス名は概念的にファイルシステムの名前とは関係がない可能性があります。find
特定の文字列がファイルを識別するために使用される場合、その文字列は「パス名」と呼ばれ、-name
使用されます。
呼び出しfind . -print
またはfind -L . -print
。この特定の呼び出しに使用されたすべてのパス名が表示されますfind
。 .-name
-name
main-file
とを使用した例では、コマンドはsl-file
ですfind -L -iname "*main*"
。-print
最後に、あなたが観察した結果は次のとおりです-print
。
./main-file # because it matches the criterion ./sl-file # because the file points to matches the criterion
ただし、そうであれば、-print
これはandが与えられたことを意味するので、これは正確なパス名であり、したがっておよびは処理する対応するデフォルト名(または)です。./main-file
./sl-file
main-file
sl-file
-name
-iname
これは不適切です。これらのデフォルト名の1つだけを使用するパターン()と一致します*main*
。そのため、結果は1つしか得られません。-name "*main*"
(または)を指定し-iname "*main*"
て発生を予測することは、一致を./sl-file
予測するのと同じです。sl-file
*main*
これは作る一部その気持ちは./main-file
二度起こると予想されます。ただし、シンボリックリンクはfind
2番目のパス名をからに変更し./sl-file
ます./main-file
。これにより、両方のパス名が一致し、両方*main*
として印刷されます./main-file
。これは起こりません。
これが必要な場合は、シンボリックリンクをbar
指して配置することを検討してください。私たちはディレクトリにあります。何を印刷する必要があります(除く)?このパス名がテストに合格したいと思うので、デフォルト名は必要です。一方、規則に応じて、パス名は(提供されたパスと同様に)で始まり、ポイントコンポーネントを含めないでください。使用できる正常で意味のあるパス名はありません。何をすべきか?幸い、この場合、ツールはパス名である.を印刷し、文字列として。/etc/fstab
/tmp/foo/
foo
find -L .
.
-name fstab
fstab
./
.
./bar
fstab
シンボリックリンクを使用しないが-name
動作する方法を示すいくつかの例:
cd /etc && find . -name . 2>/dev/null
.
これは、「実際の」(ファイルシステムの特定の)名前があるという事実にもかかわらず、etc
場合によってはディレクトリが存在する可能性がありますが、サブディレクトリを見つけることはできません.
。cd /etc && find . -name etc 2>/dev/null
etc
見つけることもできません.
。空のFAT32ファイルシステムを作成し、それを
cd
マウントポイントにマウントします。ファイルシステムは大文字と小文字を区別せず、Linuxはこれを認識しています。a
ファイルシステムに名前付きファイルを作成します。次のように実験してみてください。$ find . . ./a
a
この場合、ツールは特定の時点でファイルシステムからそれをインポートする必要があります。$ find a a $ find A A
この場合、ツールはコマンドライン引数を使用または
a
取得します。A
ファイルシステムはそのようなファイルが存在することを確認するだけです。ファイルシステム(およびオペレーティングシステム)は、この特定のファイルa
またはA
。$ find a -name A $ find A -name a
何もない!これは
-name
、ファイルシステムがファイルについて何を知っているかは関係ありません。使用されているパス名のみがfind
重要です。あなたの例と同様のことは、
-iname
ファイルシステムがシンボリックリンクとそのターゲットについて何を知っているのか気にしないことです。使用されているパス名のみがfind
重要です。
何が起こっているのかを明確にするために、次のディレクトリ構造を使用して例に戻ります。
.
├── main-file
└── sl-file -> main-file
find . -print
またはfind -L . -print
印刷:
.
./main-file
./sl-file
これはパス名です。ひも find
3つを識別するために使用されます文書(ディレクトリも文書)。文字列は.
コマンドからのもので、残りの2つは.
確認(文字列ではなくファイルを意味します)、ディレクトリタイプの理解、子孫の決定(サポートされている場合は一般的に考慮されます-prune
)-maxdepth
、および内容のリストを介して作成されますmain-file
。sl-file
この文字列は、/.sl-file
識別するファイルに対して操作が実行される前に構成されます。この文字列は、ファイルに対して操作を実行するためにfind
必要です。
ただし、ファイルに対して何もしません。そのデータやメタデータは必要ありません-name
。-print
彼らはパス名を使用します。ひも。
パス名を評価するとき、-name "*main*"
そのファイルまたはファイルシステム全体はまったく関係ありません。関連する唯一のものはパス名です。ひも;より具体的に言えば、最後のコンポーネントであるデフォルト名も次のようになります。ひも。
特定のパス名にそのパスを-name
使用したのか-L
、ファイルが最初にシンボリックリンクであるのか、指す場所であるのか、破損していないのかは重要ではありません。それは知られていると関係がありますひも。
一方、ファイルシステムクエリに似ている-type
か、クエリが必要なテストは-mtime
文書パス名で識別されます。文字列では十分ではありません。シンボリックリンクの場合は、-L
シンボリックリンクの宛先を照会するか、シンボリックリンク自体を照会するかを決定します。ただし-print
、関連する場合は、クエリの内容に関係なくパス名を印刷します。
言い換えれば:
いいえ
-L
./main-file
ひも識別する./main-file
文書タイプf
./sl-file
ひも識別する./sl-file
文書タイプl
そして
-L
./main-file
ひも識別する./main-file
文書タイプf
./sl-file
ひもまだ確認済み./main-file
文書タイプf
次に、パス名(文字列)に適用されるテストまたはタスクと、ファイルに適用されるテストまたはタスクを記録する必要があります。
-name
-print
パス名を使用するため、find . -name "*main*"
有無にかかわらず-L
印刷されます。
./main-file
-type
ファイルで機能するため、find . -type f
パス名が印刷されます。
./main-file
両方のパス名を印刷しますfind -L . -type f
。
./main-file
./sl-file