用 fdupes 删除重复文件时,如果有 a、b、c 三个目录,并且希望优先保留 a,其次保留 b,最后删除 c 中的重复文件,关键不在于写一个复杂规则,而在于目录输入顺序。
fdupes 在非交互删除模式下,会保留每组重复文件中最先出现的文件,删除后续发现的重复项。因此目录参数要按“保留优先级从高到低”排列。
也就是说,想实现“先删 c,再删 b,最后尽量保留 a”,命令应该写成:
|
|
扫描顺序是 a -> b -> c。当三个目录中存在相同文件时,a 里的文件会先被发现并保留,b 和 c 中重复的文件会被删除。如果只有 b 和 c 有重复文件,则保留 b,删除 c。
参数含义
常用参数如下:
-r:递归扫描子目录。-d:删除重复文件。-N:与-d配合使用,不进入交互确认,自动保留每组重复文件中的第一个,删除其余文件。
因此,自动删除重复文件的基本格式是:
|
|
目录越靠前,保留优先级越高;目录越靠后,越容易被删除。
先预览再删除
直接使用 -dN 会删除文件,建议先预览重复文件分组:
|
|
输出结果会按重复文件分组展示。每组中靠前的文件,就是非交互删除时更可能被保留的文件。
也可以查看统计信息:
|
|
如果数据重要,建议先把结果保存下来人工检查:
|
|
确认每组重复文件的排列顺序符合预期后,再执行:
|
|
子目录怎么处理
只要开启 -r,fdupes 会递归扫描传入目录下的所有文件。决定保留优先级的,仍然是命令中路径出现的先后顺序。
例如:
|
|
这表示:
dir_a的优先级最高。dir_b次之。dir_c最低。
如果 dir_a/sub1/file.txt 和 dir_c/sub1/file.txt 内容相同,会保留 dir_a 下的文件。如果 dir_a/x/y/file.txt 和 dir_c/file.txt 内容相同,也会优先保留 dir_a 下的文件。fdupes 比较的是文件内容,不要求文件名或目录层级完全一致。
精确控制子目录优先级
如果只传父目录,子目录内部的扫描顺序由 fdupes 的遍历逻辑决定。多数情况下,这已经够用。但如果你想让某个子目录拥有更高优先级,就要把它显式写在前面。
例如,希望优先保留 dir_a,然后保留 dir_b/special,再处理 dir_b 的其他内容,最后处理 dir_c:
|
|
这样 dir_b/special 会先于 dir_b 被扫描。之后扫描 dir_b 时,special 里的文件已经被记录,整体优先级就会高于 dir_b 的其他部分。
这个写法适合下面这种需求:
a是最重要的基准目录。b中某个子目录比b的其他内容更重要。c主要作为低优先级备份目录。
路径顺序可以继续扩展:
|
|
规则仍然只有一个:越靠前,越优先保留。
目录很多时使用列表
如果有很多目录和子目录,手动写一长串命令容易出错。可以把路径按优先级写入一个文本文件,比如 folders.txt:
|
|
然后用 xargs 传给 fdupes:
|
|
如果路径中可能包含空格,更稳妥的方式是使用空字符分隔:
|
|
需要注意的边界
第一,fdupes 比较的是文件内容,而不是文件名。如果两个文件名完全不同,但内容一致,也会被识别为重复文件。
第二,如果 a 目录内部本身就有重复文件,使用 fdupes -rdN a b c 时,a 内部靠后的重复项也可能被删除。这个命令表达的是“按整体扫描顺序保留最先出现的文件”,不是“绝对不删除 a 中任何文件”。
第三,默认情况下,fdupes 不会跟随符号链接。如果需要处理软链接相关文件,要先确认是否需要加 -s,以及这样做是否符合你的数据安全预期。
第四,fdupes 只删除重复文件,不负责清理空目录。删除完成后,如果 b、c 中留下了空文件夹,可以再运行:
|
|
更安全的操作习惯
如果目录里是重要数据,不建议一上来就执行 -rdN。更稳的流程是:
- 先运行
fdupes -r a b c查看重复分组。 - 确认每组中排在前面的文件确实应该保留。
- 再执行
fdupes -rdN a b c自动删除。 - 删除后检查是否需要清理空目录。
如果你非常担心误删 a 中的文件,可以先只对低优先级目录做更小范围的清理,或者把结果导出后人工筛选。fdupes 的目录顺序很好用,但它不是权限隔离规则;只要路径被纳入扫描,路径内部的重复文件就可能参与删除判断。
小结
用 fdupes 按优先级删除重复文件,核心就是把“想保留的目录”放在前面,把“优先删除的目录”放在后面。
想保留 a,再保留 b,优先删除 c:
|
|
想让某个子目录优先级更高,就把它单独写在父目录前面:
|
|
记住一句话就够了:fdupes -dN 会保留先出现的重复文件,删除后出现的重复文件。目录顺序,就是你的保留优先级。