【问题标题】:Find duplicates in variable在变量中查找重复项
【发布时间】:2016-01-18 05:41:20
【问题描述】:

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

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

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

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

非常感谢任何帮助!

【问题讨论】:

    标签: bash sorting find duplicates


    【解决方案1】:

    在变量中查找重复项

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

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

    yum -y install fdupes
    

    或

    apt-get install fdupes
    

    fdupes 的用法非常简单:

    fdupes /path/to/dir
    

    如果您只需要.txt 文件,您可以将结果通过管道传送到grep,即:

    fdupes /path/to/dir | grep .txt
    

    【讨论】:

    • 至少目前,OP 似乎并没有寻找具有相同内容的文件。虽然也许这只是一个尚未纠正的错误。
    • "我正在尝试在列表中找到重复项" list 来自 find 输出,所以我猜 OP 需要查找副本。
    • 是的,但是find 的输出是文件名。那些 names 然后被剥离扩展名,然后它似乎被计算为重复。里面没有任何东西读取文件的内容。
    【解决方案2】:

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

    您在空格上拆分它。这对于带有空格的文件名是不安全的。

    你也在 globbing。这对于名称中包含通配元字符的文件名是不安全的。

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

    您还可以使用-printf 参数让find 吐出任意格式的输出。 (即-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
    

    【讨论】:

      猜你喜欢
      • 2019-09-05
      • 1970-01-01
      • 1970-01-01
      • 2017-10-24
      • 2018-10-13
      • 2013-02-21
      • 2016-06-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多