我有一个包含大约 300 个文本文件的文件夹,是否有任何命令可以单独读取每个文件并删除重复的文件?我的意思是内容而不是文件名。
答案1
如果有fdupes
,它可以列出文件夹中的所有重复文件。
你可以参考这有关如何使用该fdupes
命令的在线教程。
测试
我创建了 3 个文件,名为文件1,文件2和文件3和文件1和文件2具有完全相同的内容。
现在,我执行我的命令,
fdupes -rdN .
其中(引用上述链接),
- 该
r
选项使 fdupes 递归地搜索文件。 - 该
d
选项使 fdupes 删除重复项。 - 该
N
选项与 一起使用时d
,会保留每组重复项中的第一个文件并删除其他文件,而不提示用户。
执行上述命令后,我有文件1和文件3在我的文件夹中和文件2被删除了。
答案2
皮埃尔·奥利维耶·瓦雷斯的回答需要具有-print0
并xargs -0
使用带空格的文件名等。
喜欢:
find . -type f -name "*.txt" -print0 |
xargs -0 md5sum |
awk '{print $2,$1}' |
sort -k 2 |
uniq --all-repeated=prepend -f 1 |
awk '/^$/ { I=1 }; /^./ { if (I==0) {print $1} I = 0; }' |
xargs echo
运行这个。如果它产生合理的结果,请使用xargs rm --
而不是再次运行它xargs echo
。
答案3
如果 fdupes 不可用,您还可以使用:
for first in *.txt
do
for second in *.txt
do
if diff $first $second >/dev/null 2>&1 && [ "$first" != "$second" ]
then
#echo $first and $second match. Deleting ${second}. # Optional, uncomment to use.
rm $second
fi
done
done
注意:这是非常低效的。它将对 300 个文件执行 diff 90,000 次。如果它们是相当小的文件,它仍然会很快,但如果它们是大文件,则可能需要很长时间。
答案4
作为第二个答案,当 fdupes 不可用时,更有效的方法是使用 md5 获取哈希,并使用 sort 和 uniq 来查找重复项,而无需使用双 shell 循环
像这样的东西:(全部放在一行,没有注释)
find . -type f -name '*.txt' // get recursively all .txt files
| xargs md5sum // compute the md5 sum
| awk '{print $2,$1}' // reverse the md5sum output
| sort -k 2 // sorts on the md5 hash
| uniq --all-repeated=prepend -f 1 // get groups of duplicate files
| awk '/^$/ { I=1 }; /^./ { if (I==0) {print $1} I = 0; }' // see below
| xargs rm // delete
将删除已经遇到的每个 .txt 文件
(严格地说,我忽略了 MD5 冲突的情况,因为它们在正常情况下不应该发生。)
解释 uniq 和 awk 行:
Let's assume :
file1:This is a 1st content
file2:This is a 1st content
file3:This is a 2nd content
file4:This is a 3rd content
file5:This is a 1st content
file6:This is a 3rd content
排序结果为:
file4 801620325e6bc5efa4333a9413811e23
file6 801620325e6bc5efa4333a9413811e23
file3 8f9722a09b4c6f0ddf867e268193ea1b
file1 a066d80d23803dffa9fbc1cdcd95e163
file2 a066d80d23803dffa9fbc1cdcd95e163
file5 a066d80d23803dffa9fbc1cdcd95e163
uniq --all-repeated=prepend -f 1
仅保留重复项,在每个块前面添加一个空行:
(blank line)
file4 801620325e6bc5efa4333a9413811e23
file6 801620325e6bc5efa4333a9413811e23
(blank line)
file1 a066d80d23803dffa9fbc1cdcd95e163
file2 a066d80d23803dffa9fbc1cdcd95e163
file5 a066d80d23803dffa9fbc1cdcd95e163
然后,迷你 awk 脚本忽略空行,并仅打印不跟随空行的行的第一个字段
(--> not printed: blank line)
(--> not printed: file4)
file6
(--> not printed: blank line)
(--> not printed: file1)
file2
file5
然后, xargs rm 可以 rm 剩余的文件(即重复文件)