给定一个目录,我如何找到其中所有不是硬链接文件的文件(以及任何子目录) ?或者更具体地说,那些不是具有多个参考的硬链接文件?
基本上我想扫描一个文件夹并返回该目录中唯一文件的列表,包括目录和符号链接(不是它们的目标)。如果可能,最好也忽略支持它们的文件系统(例如 HFS+)上的硬链接目录。
find
有一个应该有用的选项:
find . -type f -links 1 -print
根据定义硬链接的文件的链接计数为 2 或更大,因此这将显示所有没有其他链接的文件。
硬链接的 filea 具有相同的 inode。您可以使用stat
打印 inode 和文件名,并awk
仅在 inode 第一次出现时打印文件:
stat -c '%i %n' *csv | awk '!seen[$1]++' | cut -d ' ' -f 2-
我相信您知道,所有文件都至少有一个硬链接(在父目录中)。
要回答第一段中的问题(查找没有额外硬链接的文件),您需要区分目录和其他所有内容。假设你有 GNU Coreutils,你可以使用:
stat '%h' filename
确定给定文件名的硬链接数。否则,您可以解析ls -ld filename
-- 的输出,它应该可以工作,但ls
输出并不意味着机器可读。
对于目录以外的任何内容,如果链接数大于 1,则在某处存在指向它的硬链接。
另一方面,目录将始终具有来自其父级的通常的一个链接,加上一个用于其自己的.
条目的链接,再加上一个用于其每个直接子目录的..
条目的链接。因此,您必须确定在没有任何其他硬链接的情况下它会有多少链接,并将其与实际拥有的数量进行比较。
如果您碰巧知道您在一个禁止硬链接到目录的系统上,您可以避免这样做。(我不确定该限制通常是由操作系统还是由每个文件系统施加的。)
但这并不能解决第二段中的问题,即在目录中创建唯一文件列表。知道普通文件foo
的链接数大于 1并不能告诉您它在当前目录中是否唯一;其他硬链接可以在不同的目录中(它们只需要在同一个文件系统中)。
为此,您可以执行以下操作:
stat -c '%i %n' *
它打印当前目录中每个文件的 inode 编号和名称。然后,您可以过滤掉重复的 inode 编号以获得唯一条目。这基本上就是格伦杰克曼的回答所说的。当然*
实际上并不匹配当前目录中的所有内容;它会跳过名称以 开头的文件,.
如果某些文件的名称中包含特殊字符(如空格),则可能会导致问题。这对您来说可能无关紧要,但如果确实如此(假设 GNU 找到):
find . -maxdepth 1 -print0 | xargs -0 stat -c '%i %n'
(如果任何文件名包含换行符,这仍然会导致问题,这实际上是合法的。)
所以你想要的是任何文件/链接/目录/块/管道/...但是具有不同的 inode ?然后很容易,用 inode 列出它们,进行数字排序,最后只打印具有不同 inode 编号的那个......并提醒 find 如果你想过滤,有很多选项可以限制输出
查找 /PATH_to_SEARCH -ls | 排序-n | awk '!seen[$1]++'