根据内容将文件分组到同一目录中

时间:2018-05-28 22:05:46

标签: python python-3.x file grouping

我有一个关于对具有相同内容但文件名不同的文件进行分组的问题。我调查了filecmp.cmp(),但一次只比较两个文件。

这个想法是这样的:

file1: [a,b,c,d,e,f,g,h,i]
file2: [a,b,c,d,e,f,g,h,i]
file3: [a,b,c,d,e,f,g,h,i]
file4: [a,b,c,d,e,f,g,h]
file5: [a,b,c,d,e,f,g,h]
file6: [a,b,c,d,e]

分为:

file(1,2,3): [a,b,c,d,e,f,g,h,i]
file(4,5): [a,b,c,d,e,f,g,h]
file(6): [a,b,c,d,e]

我想我有大约1800个.txt文件,但只有大约20个唯一文件。我想创建一个列表,字典或显示分组的数据框。

感谢任何帮助。谢谢!

3 个答案:

答案 0 :(得分:1)

您可以使用SHA-1之类的哈希函数来检查具有相同内容的文件,以下是此source的摘录:

import hashlib
BLOCKSIZE = 65536

def hash_value_for(file_name):
  hasher = hashlib.sha1()
  with open(file_name, 'rb') as afile:
      buf = afile.read(BLOCKSIZE)
      while len(buf) > 0:
          hasher.update(buf)
          buf = afile.read(BLOCKSIZE)

  return hasher.hexdigest()

例如,给定文件名的上述函数将返回其内容的哈希值。

<强> FILE1.TXT

  

这是一个测试。

<强> FILE2.TXT

  

这是一个测试!

<强> file3.txt

  

这是一个测试。

<强>输出:

print(hash_value_for("file1.txt"))
> 0828324174b10cc867b7255a84a8155cf89e1b8b
print(hash_value_for("file2.txt"))
> cc4bc53ee478380f385721b45247107338a9cec3
print(hash_value_for("file3.txt"))
> 0828324174b10cc867b7255a84a8155cf89e1b8b

现在回到原来的例子:

<强>文件:

假设我们有以下文件,每个文件都包含以下内容:

file1: [a,b,c,d,e,f,g,h,i]
file2: [a,b,c,d,e,f,g,h,i]
file3: [a,b,c,d,e,f,g,h,i]
file4: [a,b,c,d,e,f,g,h]
file5: [a,b,c,d,e,f,g,h]
file6: [a,b,c,d,e]

<强>代码:

import hashlib
import itertools

BLOCKSIZE = 65536


def hash_value_for(file_name):
    hasher = hashlib.sha1()
    with open(file_name, 'rb') as afile:
        buf = afile.read(BLOCKSIZE)
        while len(buf) > 0:
            hasher.update(buf)
            buf = afile.read(BLOCKSIZE)

    return hasher.hexdigest()


file_names = ["file1.txt", "file2.txt", "file3.txt",
              "file4.txt", "file5.txt", "file6.txt"]

file_names_with_hash_values = {}
for file_name in file_names:
    file_names_with_hash_values[file_name] = hash_value_for(file_name)

result = {}
for key, value in sorted(file_names_with_hash_values.items()):
    result.setdefault(value, []).append(key)

print(result)

<强>输出:

{'e99a894b164a9274e7dabc1b77b41f4148860d96': ['file1.txt', 'file2.txt', 'file3.txt'], 
'bf141159c6499f26f46c7bdc28914417ff66aa15': ['file4.txt', 'file5.txt'], 
'a019bdc760a550cdc55de1343d4ebbcff1ba49c3': ['file6.txt']}

这只是一个示例,您可以更改代码以满足您的需求(并获得所需的输出)。

答案 1 :(得分:0)

假设您有6个文件作为

处理
- my_files/
    - file1.txt
    - file2.txt
    - file3.txt
    - file4.txt
    - file5.txt
    - file6.txt

然后您可以将它们作为字符串阅读,并使用pandas为您完成所有工作

with open("my_files/file1.txt"),
     open("my_files/file2.txt"),
     open("my_files/file3.txt"),
     open("my_files/file4.txt"),
     open("my_files/file5.txt"),
     open("my_files/file6.txt") as file1, file2, file3, file4, file5, file6:


     df = pd.DataFrame({"values": [file1.read(), file2.read(), file3.read(), 
                          file4.read(), file5.read(), file6.read()], 
                        "f":["file1", "file2", "file3", "file4", "file5", "file6"]})

使用groupby

>>> df.groupby("values", as_index=False).agg({"f": ",".join})

    values                f
0   [a,b,c,d,e,f,g,h,i]   file1,file2,file3
1   [a,b,c,d,e,f,g,h]     file4,file5
2   [a,b,c,d]             file6

答案 2 :(得分:0)

一种经典的方法是使用词典。首先编译目录中所有文件名的列表,并将其存储到名为file_names的列表中。然后:

filedict={}
for name in file_names:
    file=open(name,"r")
    filecontents=file.read()
    if filecontents in filedict:
        filedict[filecontents].append(name)
    else:
        filedict[filecontents]=[]
        filedict[filecontents].append(name)

此词典的每个值都是具有相同文本内容的文件列表。字典的键是文件的字符串。