查找具有相同名称但内容不同的文件

时间:2015-05-10 02:58:20

标签: python linux sed

我需要在包含大量文件的linux文件夹结构中找到具有相同名称但内容不同的文件。

这样的工作部分地完成了工作,如何消除具有不同内容的文件?

#!/bin/sh 
dirname=/path/to/directory
find $dirname -type f | sed 's_.*/__' | sort|  uniq -d| 
while read fileName
do
find $dirname -type f | grep "$fileName"
done

How to find duplicate filenames (recursively) in a given directory? BASH

非常感谢!

2 个答案:

答案 0 :(得分:1)

第一个问题是,如何确定两个文件是否具有相同的内容?

一个明显的可能性是读取(或mmap)两个文件并一次比较一个块。在某些平台上,statread要快得多,因此您可能需要首先比较尺寸。还有其他一些可能有用的优化,取决于你实际做了什么(例如,如果你要运行数千次,并且大多数文件每次都相同,你可以哈希并缓存哈希值,只在哈希值匹配时检查实际文件)。但是我怀疑你是否过于担心如果你的现有代码是可接受的那种性能调整(因为它为树中的每个文件搜索整个树一次),所以让我们做最简单的事情。

这是在Python中实现它的一种方法:

#!/usr/bin/env python3
import sys

def readfile(path):
    with open(path, 'rb') as f:
        return f.read()

contents = [readfile(fname) for fname in sys.argv[1:]]
sys.exit(all(content == contents[0] for content in contents[1:]))

如果所有文件都相同,则将以代码1退出,如果任何文件对不同,则代码0。因此,将其另存为allequal.py,使其成为可执行文件,并且您的bash代码只能对allequal.py的结果运行grep,并使用退出值(例如,通过{{1 }})决定是否为你打印这些结果。

答案 1 :(得分:0)

我正面临与问题中所述相同的问题。在大型目录树中,某些文件具有相同的名称,相同的内容或不同的内容。内容不同的内容需要人工关注,以决定每种情况下的解决方法。我需要创建这些文件的列表来指导操作人员。

问题中的代码和abernet响应中的代码都很有帮助。这是将两者结合的方式:将来自abernet响应的python代码存储在某个文件中,例如/ usr / local / bin / do_these_files_have_different_content:

sudo tee /usr/local/bin/do_these_files_have_different_content <<EOF
#!/usr/bin/env python3
import sys

def readfile(path):
    with open(path, 'rb') as f:
        return f.read()

contents = [readfile(fname) for fname in sys.argv[1:]]
sys.exit(all(content == contents[0] for content in contents[1:]))
EOF

sudo chmod a+x /usr/local/bin/do_these_files_have_different_content

然后将Illusionist问题中的bash代码扩展为在需要时调用该程序,并对结果作出反应:

#!/bin/sh 
dirname=$1
find $dirname -type f | sed 's_.*/__' | sort|  uniq -d| 
while read fileName
do
if do_these_files_have_different_content $(find $dirname -type f | grep "$fileName")
then find $dirname -type f | grep "$fileName"
     echo
fi
done

这将写入所有具有相同名称但内容不同的文件的路径,以stdout。名称相同但内容不同的文件组用空行分隔。我将外壳程序脚本存储在/ usr / local / bin / find_files_with_same_name_but_different_content中,并以

调用
find_files_with_same_name_but_different_content /path/to/my/storage/directory