按名称查找重复文件,忽略子目录中的大小写

按名称查找重复文件,忽略子目录中的大小写

如何在 Linux 系统上列出重复的文件名

  • 忽略案件
  • 包括所有子目录

文件不应该按它们的不同进行比较内容但只能通过他们的名字。输出应该是包含路径的文件名列表,以便可以对这些文件运行进一步的命令。

假设我们有

ls -1R /tmp/
foo
BAR
barfoo
a/BAr
a/b/bar
c/bAr

过滤/查找脚本的输出应该是

/tmp/BAR
/tmp/a/BAr
/tmp/a/b/bar
/tmp/c/bAr

答案1

find . -printf "%p %f\n" | sort -f -k2 | uniq -Di -f1

find如果您不想从以下位置开始,请指定您选择的起始目录.-type f如果您只想添加文件名称。 

  • find命令按目录顺序(即,就您而言,随机顺序)生成文件(和目录)名称列表。
  • -printf "%p %f\n"打印完整路径名(相对于.)和文件名。 
  • sort -f是 的缩写sort --ignore-case,即,它以不区分大小写的方式对文件名列表进行排序
  • -k2告诉它使用第二个字段作为排序键。 
  • uniq -Di -f1是 的缩写,即,它根据第二个字段及其他字段(即具有相同(不区分大小写)的文件名)的不区分大小写的比较,uniq --all-repeated --ignore-case --skip-fields=1显示重复出现的(所有)输出行。find

这应该会为您提供所需的输出,但每行末尾都会重复文件名。如果你想摆脱它,请输入sed 's/ .*//'.

一些问题:

  • 如果你有目录它们的名称除了大小写之外都相同,并且它们包含名称除了大小写之外都相同的文件,例如,

    documents/design.doc
    Documents/Design.doc
    

    然后这些将被列出。

  • 如果您的文件(或目录)的名称包含空格、制表符或换行符,则会中断。

答案2

这适用于基本文件名,但不适用于带有回车符和可能其他一些边缘情况的文件。

FilesNoPath=$(find . -printf "%f\n")
FilesWithPath=$(find .)

oldIFS=$IFS
IFS=$'\n'
for filename in $FilesNoPath;
do
    Matches=$(echo "$FilesWithPath" | grep -i "/$filename$")
    if [ $(echo "$Matches" | wc -l) -gt 1 ]
    then
        echo Found matches:
        echo "$Matches"
        FilesWithPath=$(echo "$FilesWithPath" | grep -vi "/$filename$")
    fi
done
IFS=$oldIFS

如果您希望输出显示完整路径和/或您不想从匹配文件的父目录中执行此命令,则可以将.两个 find 命令中的替换为 。/path/to/your/files

相关内容