删除重复文件

AvL*_*AvL 6 osx find regular-expression

在我的 Mac OS X 10.6.7 上,iTunes 复制了我音乐库中的每个文件。现在我有 3,840 个文件而不是 1,920 个。问题是 iTunes 不是简单地复制整个文件夹,而是复制每个文件夹中的每个文件,1在副本中添加一个。它看起来像这样:

??? album1
?   ??? track1.mp3
?   ??? track1 1.mp3
?   ??? track2.mp3
?   ??? track2 1.mp3
??? album2
    ??? track1.m4a
    ??? track1 1.m4a
Run Code Online (Sandbox Code Playgroud)

现在,我不想点击 1,920 个重复项,而是想在终端中输入一些智能行来删除多余的文件:

find path/to/music/ -name "* 1.*" -delete

虽然这在大多数情况下都有效,但在以下情况下会搞砸:

??? album2
    ??? track 1.mp3
    ??? track 1 1.mp3
Run Code Online (Sandbox Code Playgroud)

也许我应该排除"* 1 1.*"并稍后重命名这些文件以删除多余的1

我该怎么做呢?

有没有简单的解决方案?

小智 5

我还要补充一点,为了成功找到(并删除)确切的文件重复项,您必须通过哈希比较文件:

#!/bin/sh -eu
find "${1:-.}" -type f ! -empty -print0 | xargs -0 md5 -r | \
    awk '$1 in a{sub("^.{33}","");printf "%s\0",$0}a[$1]+=1{}' | \
    xargs -0 rm -v --
Run Code Online (Sandbox Code Playgroud)

将其另存为deldupes.sh并运行它,将 dirname 作为第一个参数(否则$PWD将被使用)。

在 OS X 上测试,适用于长空白文件名。


小智 4

像这样的东西,没有测试过;它是在 bash 中,所以你可能需要转换一些语法:

IFS=$'\n'              # so that only newlines separate words, not spaces
set -f                 # disable globbing
FILES=$(find path/to/music/ -name "* 1.*")

for FILE in ${FILES}; do
    if [[ -f "${FILE% 1.*}" ]] ; do
        echo "Matched ${FILE}."
        # rm "${FILE}" # Uncomment me once you have confirmed it would do what you intend.
    fi
done
Run Code Online (Sandbox Code Playgroud)

${FILE% 1.*}1.*从末尾删除最后一个匹配的语法,[[ -f ... ]]检查该文件是否存在;因此,它将删除那些末尾没有语法的文件所存在的文件。请在取消注释之前进行测试rm,以确保其正确。