使用 Bash 删除特定目录中的重复文件,并将其保留在另一个目录中

使用 Bash 删除特定目录中的重复文件,并将其保留在另一个目录中

我在这里看到了一些关于在各种情况下删除重复文件的问题,但我找不到任何与我想要完成的内容相关的内容。

我最接近看到的答案是在这里删除重复文件,仅保留最新文件但我尝试修改,但得到了一个错误的替换错误

f=(${(f)files})

可能是因为我运行的是 bash shell 而不是 zsh shell。

我有多个基于日期的目录。每个目录内都有许多子目录和文件。其中一些文件是重复的,它们可能位于同一个子目录中,也可能位于不同的子目录中。

例如

backup
  /2022-09-01
    /photos 
      image_a.jpg
      image_b.jpg
      image_c.jpg

backup
  /2022-09-02
    /photos 
      /album
        image_a.jpg
      image_b.jpg
      image_c.jpg
      image_d.jpg

backup
  /2022-09-03
    /photos 
      /album
        image_a.jpg
      image_b.jpg
      image_d.jpg

我想要做的是删除除最新目录中的文件之外的重复文件。

因此在上面的例子中,脚本运行后将保留

backup
  /2022-09-01
    /photos 

backup
  /2022-09-02
    /photos 
      /album
      image_c.jpg

backup
  /2022-09-03
    /photos 
      /album
        image_a.jpg
      image_b.jpg
      image_d.jpg

我可以找到所有文件,根据哈希值等获取重复项,但我无法弄清楚如何删除以前目录中的文件。

答案1

jdupes-d可以使用其( ) 选项来完成--delete

如果 的所有直接子目录backup都按照模式命名,YYYY-MM-DD那么默认的按名称排序应该有效,您只需将其反转(-i)。这是因为按 排序表示的日期YYYY-MM-DD与您期望的一样。手册指出默认排序是“按文件名”,但我的测试表明它更像是“按路径名”。我的意思是目录组件的名称确实很重要。

您可以选择按修改时间排序:-o time,倒置(-i)。如果 的直接子目录的backup名称不符合模式,这将很有帮助YYYY-MM-DD;但您需要确保子目录的内容按您期望的顺序进行修改。如果您每天在此文件系统中创建子目录,则应该如此。如果您从另一个文件系统一次性复制它们,则它们的修改时间可能或者可能不会按您想要的顺序。

我认为在这种情况下按名称排序是可以的。首先你可以尝试:

jdupes -rid backup

并以交互方式询问您要保留哪些重复文件*。这将允许您确保工具按您想要的顺序列出重复项。如果该工具被告知只自动保留一个重复项(而不提示您),它将保留第一的每个列表一个。

请注意,此试运行可能需要很长时间,工具才会首次提示您。但我建议运行它,只是为了查看几组重复项并确保每个列表的顺序符合您的期望。

如果看起来不错,则中止试运行(Ctrl+ c)并告诉工具自动删除(-N):

jdupes -ridN backup

不幸的是,在试运行期间出现提示时,您无法选择“切换”剩余集的自动模式(至少在jdupes我测试的 1.20.2 中是这样)。您必须中止并重新开始-N,接受试运行的努力将白费的事实。

如果您怀疑默认顺序-o name或替代顺序都无法-o time提供您想要的顺序,请考虑-O

-O --param-order
按命令行参数顺序对输出文件进行排序

因此你可以这样做:

jdupes -rdN backup/september backup/august backup/july

作为最后的手段,您可以以-N交互方式省略和检查每组;或者省略-d并使用某些自定义工具或脚本来解析输出。

笔记:

  • jdupes根据内容查找重复项。名称与此无关。

  • jdupes会帮您找到重复文件,无论它们是在不同的YYYY-MM-DD子目录中还是在同一个子目录中。例如,位于 中的文件2022-09-03及其副本2022-09-03仍将被视为重复文件,并将-dN删除所有副本,只留下一个副本。


* 警告:n是最具破坏性的选项,它意味着“保持没有任何“。”a是最安全的选项,它意味着“保留全部”。我之所以提到这一点,是因为许多其他工具会询问“您确定要删除吗?”或“覆盖?”,或任何类似“继续销毁?”的问题;在这些情况下,n意味着“否”是一个安全的选项,您可能已经习惯了它。但是,在 中不是这样jdupes

相关内容