通过shell脚本查找*不是*硬链接的文件

时间:2013-04-29 15:34:30

标签: shell hardlink

给定一个目录,如何查找硬链接文件中的所有文件(以及任何子目录)?或者更具体地说,那些不是具有多个引用的硬链接文件?

基本上我想扫描一个文件夹并返回该目录中的唯一文件列表,包括目录和符号链接(不是它们的目标)。如果可能的话,最好还忽略支持它们的文件系统上的硬链接目录(例如HFS +)。

4 个答案:

答案 0 :(得分:15)

find有一个应该有用的选项:

find . -type f -links 1 -print

按定义硬链接的文件的链接数为2或更大,因此这将显示所有没有其他链接的文件。

答案 1 :(得分:5)

硬链接文件具有相同的inode。您可以使用stat打印inode和文件名,并使用awk仅在第一次出现inode时打印文件:

stat -c '%i %n' *csv | awk '!seen[$1]++' | cut -d ' ' -f 2-

答案 2 :(得分:1)

我确定您知道,所有文件至少有一个硬链接(在父目录中)。

要回答第一段中的问题(查找不具备其他硬链接的文件),您需要区分目录和其他所有内容。假设你有GNU Coreutils,你可以使用:

stat '%h' filename

确定给定文件名的硬链接数。否则,您可以解析ls -ld filename的输出 - 这应该有效,但ls输出并不是真正意味着机器可读。

对于目录以外的任何内容,如果链接数大于1,那么就会在某处提供硬链接。

另一方面,目录始终具有来自其父目录的通常一个链接,另外一个用于其自己的.条目,另外一个用于每个<{1}}条目的一个< / em>的直接子目录。因此,您必须确定在没有任何其他硬链接的情况下它将拥有多少链接,并将其与实际数量进行比较。

如果您碰巧知道自己是在禁止指向目录的硬链接的系统上,则可以避免这样做。 (我不确定这种限制是否通常由操作系统或每个文件系统强加。)

但是,这并没有解决第二段中的问题,在目录中创建一个唯一文件列表。知道普通文件..的链接数大于1 并不告诉您它是否在当前目录中是唯一的;其他硬链接可以在不同的目录中(它们只需要在同一个文件系统中)。

为此,您可以执行以下操作:

foo

打印当前目录中每个文件的inode编号和名称。然后,您可以过滤掉重复的inode编号以获取唯一条目。这基本上是glenn jackman's answer所说的。当然stat -c '%i %n' * 实际上并不匹配当前目录中的所有;它会跳过名称以*开头的文件,如果某些文件的名称中包含特殊字符(如空格),则会导致问题。这可能对你没有关系,但如果确实如此(假设GNU找到):

.

(如果任何文件名包含换行符,这仍然会导致问题,这实际上是合法的。)

答案 3 :(得分:1)

所以你想要的是文件/链接/ dir / block / pipe / ...但是使用不同的inode? 然后它很容易,用inode列出它们,做一个数字排序,最后只打印一个具有不同inode号的那个...并且提醒find有很多选项来限制输出,如果你想过滤

查找/ PATH_to_SEARCH -ls | sort -n | awk&#39;!看过[$ 1] ++&#39;