【问题标题】:How to create a os.walk() function which compares the folders and subfolders of two directories?如何创建一个比较两个目录的文件夹和子文件夹的 os.walk() 函数?
【发布时间】:2020-01-30 03:36:59
【问题描述】:

这是我的问题:假设我想创建一个文件同步功能,它遍历两个相似目录的所有文件夹和子文件夹,并检测这两个目录的所有公共文件夹/子文件夹。我通过将 os.walk 模块与 filecmp 模块结合起来进行了尝试。到目前为止,我的代码如下所示:

import filecmp
import os

src=r"C:\Users\j2the\Documents\Test3"
dst=r"C:\Users\j2the\Documents\Test4"


comparison = filecmp.dircmp(dst, src)

for dirpath,dirnames,filenames in os.walk(src):
    for folders in dirnames:
        if folders in comparison.common_dirs:
            print(folders)
            src_folder=os.path.abspath(os.path.join(dirpath,folders))
            dst_folder=os.path.abspath(os.path.join(dst,folders))
            folder_comparison = filecmp.dircmp(dst_folder, src_folder)

            for dirpath1,dirnames1,filenames1 in os.walk(src_folder):

                for subfolders in dirnames1:
                    if subfolders in folder_comparison.common_dirs:
                        print(subfolders)
                        src_subfolder=os.path.abspath(os.path.join(dirpath1,subfolders))
                        dst_subfodler=os.path.abspath(os.path.join(dst_folder,subfolders))
                        subfolder_comparison=filecmp.dircmp(dst_subfodler,src_subfolder)

这是一个非常简单的代码。但是,此代码仅适用于具有最大值的目录。 2 个子文件夹。如果我想分析具有更多子文件夹的目录,我将不得不在我的代码中添加大量嵌套循环。当然还有另一种方法可以做到这一点,对吧?我正在考虑创建一个 while 循环,不断遍历每个子文件夹并比较它们直到没有子文件夹,但我根本不知道该怎么做。任何帮助/输入将不胜感激!

【问题讨论】:

  • os.walk 不是为每个子文件夹生成一个元组吗?

标签: python for-loop os.walk file-comparison


【解决方案1】:

您不需要filecmp.dircmp。相反,使用您要比较的两个目录对os.walk 进行两次调用,zip 是两个生成器的输出,并在输出中的两个子目录上使用集合交集来查找公共子目录。

请注意,使递归遍历工作的关键是对两个生成器返回的子目录执行就地替换,以便仅保留两个当前目录共有的子目录以进行更深入的遍历和进一步比较:

import os
for (root1, dirs1, _), (root2, dirs2, _) in zip(os.walk('dir1'), os.walk('dir2')):
    dirs1[:] = dirs2[:] = set(dirs1).intersection(dirs2)
    for common_dir in dirs1:
      print('Common sub-directory of {} and {}: {}'.format(root1, root2, common_dir))

来自os.walk的文档:

topdownTrue时,调用者可以就地修改dirnames列表 (可能使用del 或切片赋值),而walk() 只会递归 进入名称保留在dirnames 中的子目录;这可以是 用于修剪搜索...

【讨论】:

    【解决方案2】:

    这是一个有效的简单技巧(在 Mac 上测试)。 os.walk 函数返回目录树的生成器,可以将其生成为列表。但是,由于根目录名称可能不同,我删除了每个列表项中的第一个元素。

    编辑:这只比较目录结构而不是内容。

    res1 = [r[1:] for r in os.walk(src)]
    res2 = [r[1:] for r in os.walk(dst)]
    
    comparison = res1 == res2
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-18
      • 2020-12-20
      相关资源
      最近更新 更多