从:http://www.chriswrites.com/2012/02/how-to-find-and-delete-duplicate-files-in-mac-os-x/ 我该如何修改它以仅删除它看到的文件的第一个版本。
从 Spotlight 或 Utilities 文件夹打开终端 使用 cd 命令切换到您要搜索的目录(文件夹)(包括子文件夹)。在命令提示符下输入 cd 例如 cd ~/Documents 将目录更改为您的主 Documents 文件夹 在命令提示符下,输入以下命令:
find . -size 20 \! -type d -exec cksum {} \; | sort | tee /tmp/f.tmp | cut -f 1,2 -d ' ' | uniq -d | grep -hif – /tmp/f.tmp > duplicates.txt
此方法使用简单的校验和来确定文件是否相同。重复项的名称将列在当前目录中名为 duplicates.txt 的文件中。打开此文件以查看相同文件的名称现在有多种方法可以删除重复项。要删除文本文件中的所有文件,请在命令提示符下键入:
while read file; do rm "$file"; done < duplicates.txt
答案1
首先,您必须重新排序第一个命令行,以便保持 find 命令找到的文件的顺序:
find . -size 20 ! -type d -exec cksum {} \; | tee /tmp/f.tmp | cut -f 1,2 -d ‘ ‘ | sort | uniq -d | grep -hif – /tmp/f.tmp > duplicates.txt
(注意:为了在我的计算机上进行测试,我使用了find . -type f -exec cksum {} \;
)
其次,打印除第一个重复项之外的所有重复项的一种方法是使用辅助文件,比如说/tmp/f2.tmp
。然后我们可以执行以下操作:
while read line; do
checksum=$(echo "$line" | cut -f 1,2 -d' ')
file=$(echo "$line" | cut -f 3 -d' ')
if grep "$checksum" /tmp/f2.tmp > /dev/null; then
# /tmp/f2.tmp already contains the checksum
# print the file name
# (printf is safer than echo, when for example "$file" starts with "-")
printf %s\\n "$file"
else
echo "$checksum" >> /tmp/f2.tmp
fi
done < duplicates.txt
在运行此操作之前,只需确保它/tmp/f2.tmp
存在并且为空,例如通过以下命令:
rm /tmp/f2.tmp
touch /tmp/f2.tmp
希望这有帮助=)
答案2
另一个选择是使用 fdupes:
brew install fdupes
fdupes -r .
fdupes -r .
在当前目录下递归查找重复文件。添加-d
以删除重复文件 — 系统将提示您要保留哪些文件;如果您添加-dN
,fdupes 将始终保留第一个文件并删除其他文件。
答案3
我编写了一个脚本,可以重命名您的文件以匹配其内容的哈希值。
它使用文件字节的子集,因此速度很快,并且如果发生冲突,它会在名称后附加一个计数器,如下所示:
3101ace8db9f.jpg
3101ace8db9f (1).jpg
3101ace8db9f (2).jpg
这样,您可以轻松地自行查看和删除重复项,而无需过度信任其他人的软件来处理您的照片。
脚本: https://gist.github.com/SimplGy/75bb4fd26a12d4f16da6df1c4e506562
答案4
这是在 EagleFiler 应用程序的帮助下完成的,该应用程序由蔡崇信。
tell application "EagleFiler"
set _checksums to {}
set _recordsSeen to {}
set _records to selected records of browser window 1
set _trash to trash of document of browser window 1
repeat with _record in _records
set _checksum to _record's checksum
set _matches to my findMatch(_checksum, _checksums, _recordsSeen)
if _matches is {} then
set _checksums to {_checksum} & _checksums
set _recordsSeen to {_record} & _recordsSeen
else
set _otherRecord to item 1 of _matches
if _otherRecord's modification date > _record's modification date
then
set _record's container to _trash
else
set _otherRecord's container to _trash
set _checksums to {_checksum} & _checksums
set _recordsSeen to {_record} & _recordsSeen
end if
end if
end repeat
end tell
on findMatch(_checksum, _checksums, _recordsSeen)
tell application "EagleFiler"
if _checksum is "" then return {}
if _checksums contains _checksum then
repeat with i from 1 to length of _checksums
if item i of _checksums is _checksum then
return item i of _recordsSeen
end if
end repeat
end if
return {}
end tell
end findMatch
您还可以使用建议的重复文件删除程序自动删除重复项这个帖子。