在 bash 中,如何删除同一文件的多个版本?

In bash, how can I remove multiple versions of the same file?

这可能是一个非常具体的案例,但我对 bash 知之甚少,我需要删除“重复”文件。这几天我一直在下载完全合法的视频游戏 rom,我注意到很多包都有同一个游戏的许多不同版本,如下所示:

Awesome Golf (1991).lnx
Awesome Golf (1991) [b1].lnx
Baseball Heroes (1991).lnx
Baseball Heroes (1991) [b1].lnx
Basketbrawl (1992).lnx
Basketbrawl (1992) [a1].lnx
Basketbrawl (1992) [b1].lnx
Batman Returns (1992).lnx
Batman Returns (1992) [b1].lnx

我如何制作一个 bash 脚本来删除重复项?副本可以是具有相同名称的任何文件,名称可以是第一个括号之前的字符串。该脚本应该解析所有文件并获取它们的名称,查看哪些名称匹配以检测重复项,并删除除第一个文件之外的所有文件(第一个是按字母顺序出现的第一个文件)。

请您尝试以下操作:

#!/bin/bash

dir="dir"                               # the directory where the rom files are located
declare -A seen                         # associative array to detect the duplicates
while IFS= read -r -d "" f; do          # loop over filenames by assigning "f" to it
    name=${f%(*}                        # extract the "name" by removing left paren and following characters
    name=${name%.*}                     # remove the extension considering the case the filename doesn't have parens
    name=${name%[*}                     # remove the left square bracket and following characters considering the case as above
    name=${name%% }                     # remove trailing whitespaces, if any
    if (( seen[$name]++ )); then        # if the name duplicates...
        # remove "echo" if the output looks good
        echo rm -- "$f"                 # then remove the file
    fi
done < <(find "$dir" -type f -name "*.lnx" -print0 | sort -z -t "." -k1,1)
                                        # sort the list of filenames in alphabetical order
  • 请将第一个 dir= 行修改为您保存 rom 文件的目录路径。
  • echo 命令仅打印要删除的文件名作为预演。如果输出看起来不错,则删除 echo 并执行真正的

[说明]

  • 关联数组seen将提取的“名称”与 外观计数器。如果计数器非零,则文件是重复的 一个并且可以删除(只要文件排序正确)。
  • -print0 选项 find-z 选项 sort-d "" read 的选项使空字符作为文件名的分隔符 接受包含特殊字符(例如空格)的文件名, 制表符、换行符等