在 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
的选项使空字符作为文件名的分隔符
接受包含特殊字符(例如空格)的文件名,
制表符、换行符等
这可能是一个非常具体的案例,但我对 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
的选项使空字符作为文件名的分隔符 接受包含特殊字符(例如空格)的文件名, 制表符、换行符等