我试图在列表中找到重复项。现在我正在搜索具有特定文件扩展名的文件列表,并将这些文件存储在名为“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
非常感谢任何帮助!!
答案 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
包含单个文件名。您无法sort
或uniq
单个项目。
将上述所有内容放在一起并假设您想要通过无后缀名称(而不是文件内容)检测重复项,然后......
如果您不担心带换行符的文件名,那么您可以使用它:
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