ご存じのとおり、すべてのファイルには (親ディレクトリ内に) 少なくとも 1 つのハード リンクがあります。
最初の段落の質問 (追加のハードリンクを持たないファイルの検索) に答えるには、ディレクトリとその他すべてを区別する必要があります。GNU Coreutils があると仮定すると、以下を使用できます。
stat '%h' filename
特定のファイル名のハード リンクの数を決定します。それ以外の場合は、 -- の出力を解析できますが、ls -ld filename
これは機能するはずですが、ls
出力は実際には機械可読であることを意図していません。
ディレクトリ以外の場合、リンクの数が 1 より大きい場合、そのディレクトリへのハード リンクがどこかに存在します。
一方、ディレクトリには常に、その親からの通常の 1 つのリンクと、それ自体の.
エントリ用のリンク、およびその直下の各..
サブディレクトリのエントリ用の 1 つのリンクがあります。そのため、追加のハード リンクがない場合のリンクの数を決定し、それを実際の数と比較する必要があります。
ディレクトリへのハードリンクを禁止しているシステムを使用していることがわかっている場合は、これを避けることができます。(通常、その制限が OS によって課されているのか、それとも各ファイルシステムによって課されているのかはわかりません。)
しかし、それではディレクトリ内の一意のファイルのリストを作成する 2 番目の段落の問題は解決しません。プレーン ファイルfoo
のリンク数が 1 より大きいことを知っていても、それが現在のディレクトリ内で一意であるかどうかはわかりません。他のハード リンクは別のディレクトリにある可能性があります (単に同じファイル システムにある必要があります)。
これを行うには、次のようなことができます。
stat -c '%i %n' *
これは、現在のディレクトリ内の各ファイルの inode 番号と名前を出力します。その後、重複する inode 番号を除外して、一意のエントリを取得できます。これは基本的に、グレン・ジャックマンの答えが言っていることです。もちろん*
、実際には現在のディレクトリ内のすべてに一致するわけではありません。名前が で始まるファイルをスキップし.
、一部のファイルの名前に特殊文字 (スペースなど) が含まれていると問題が発生する可能性があります。それはあなたにとって重要ではないかもしれませんが、もしそうなら (GNU find を仮定して):
find . -maxdepth 1 -print0 | xargs -0 stat -c '%i %n'
(ファイル名に改行文字が含まれていると問題が発生しますが、これは実際には有効です。)