如何删除目录中的重复文件?

kev*_*kev 28 bash

我在一个目录中下载了很多图像。
下载器重命名已经存在的文件。
我还手动重命名了一些文件。

a.jpg
b.jpg
b(2).jpg
hello.jpg      <-- manually renamed `b(3).jpg`
c.jpg
c(2).jpg
world.jpg      <-- manually renamed `d.jpg`
d(2).jpg
d(3).jpg
Run Code Online (Sandbox Code Playgroud)

如何删除重复的?结果应该是:

a.jpg
b.jpg
c.jpg
world.jpg
Run Code Online (Sandbox Code Playgroud)

注意:名称无关紧要。我只想要 uniq 文件。

Jak*_*kob 53

fdupes是您选择的工具。要在当前目录中查找所有重复文件(按内容,而不是按名称):

fdupes -r .
Run Code Online (Sandbox Code Playgroud)

要手动确认删除重复文件:

fdupes -r -d .
Run Code Online (Sandbox Code Playgroud)

要自动删除除每个重复文件中的第一个之外的所有副本(请注意,此警告实际上会根据要求删除文件):

fdupes -r -f . | grep -v '^$' | xargs rm -v
Run Code Online (Sandbox Code Playgroud)

我建议在删除之前手动检查文件:

fdupes -rf . | grep -v '^$' > files
... # check files
xargs -a files rm -v
Run Code Online (Sandbox Code Playgroud)

  • 此外,较新版本的 fdupes 具有内置选项,可以删除重复文件列表中除第一个之外的所有文件:`fdupes -rdN .` 其中 -r 是递归的,-d 是删除,-N 是无提示 (4认同)
  • @DanielWolf 尝试使用 xargs 选项 `-d '\n'` (2认同)

Sie*_*geX 30

bash 4.x

#!/bin/bash
declare -A arr
shopt -s globstar

for file in **; do
  [[ -f "$file" ]] || continue
   
  read cksm _ < <(md5sum "$file")
  if ((arr[$cksm]++)); then 
    echo "rm $file"
  fi
done
Run Code Online (Sandbox Code Playgroud)

这既是递归的,也可以处理任何文件名。缺点是它需要 4.x 版才能使用关联数组和递归搜索。echo如果您喜欢结果,请删除。

呆呆的版本

gawk '
  {
    cmd="md5sum " q FILENAME q
    cmd | getline cksm
    close(cmd)
    sub(/ .*$/,"",cksm)
    if(a[cksm]++){
      cmd="echo rm " q FILENAME q
      system(cmd)
      close(cmd)
    }
    nextfile
  }' q='"' *
Run Code Online (Sandbox Code Playgroud)

请注意,这仍然会破坏名称中包含双引号的文件。没有真正的方法来解决这个问题awkecho如果您喜欢结果,请删除。