在变量中查找重复项

时间:2015-10-19 18:56:05

标签: bash sorting find duplicates

我试图在列表中找到重复项。现在我正在搜索具有特定文件扩展名的文件列表,并将这些文件存储在名为“files”的变量中。

对于文件中的每个文件,我正在格式化这些文件,因此只有文件名。

然后我想检查此列表是否有重复项,但我无法理解它。

files=$(find /root/123 -type f \( -iname "*.txt" -o -iname "*.bat" \))

for file in $files; do
   formatted=$(echo ${file##*/})
   unique=$(echo $formatted | sort | uniq -c)
done

echo $unique

非常感谢任何帮助!!

2 个答案:

答案 0 :(得分:2)

  

在变量

中查找重复项

我想你不需要重新发明轮子,只需使用fdupes ot fslint

根据您的系统,您可以使用以下方法安装它:

yum -y install fdupes

apt-get install fdupes

使用fdupes非常简单:

fdupes /path/to/dir

如果您只需要.txt个文件,可以将结果传递给grep,即:

fdupes /path/to/dir | grep .txt

答案 1 :(得分:1)

$files不是数组。这是一个字符串。

你是在空白上拆分它。对于包含空格的文件名,这是不安全的。

你也是全球化的。对于名称中带有全局元字符的文件名,这是不安全的。

请参阅Bash FAQ 001了解如何逐行安全地操作数据。另请参阅Don't read lines with for

您还可以find使用-printf参数吐出任意格式化的输出。 (即-printf %f将仅打印出文件名(无路径信息)。)

您不需要echo来进行变量分配。 (即formatted=${file##*/}工作正常。)

$formatted包含单个文件名。您无法sortuniq单个项目。

将上述所有内容放在一起并假设您想要通过无后缀名称(而不是文件内容)检测重复项,然后......

如果您不担心带换行符的文件名,那么您可以使用它:

find /root/123 -type f \( -iname "*.txt" -o -iname "*.bat" \) -printf %f | sort | uniq -c

如果你 担心他们,那么你需要手动读取这些行(对于bash 4 +这样的话):

declare -A files
while IFS= read -r -d '' file; do
    ((files["$file"]+=1))
done <(find /root/123 -type f \( -iname "*.txt" -o -iname "*.bat" \) -printf '%f\0')
declare -p files