簡體   English   中英

使用python區分兩個文件夾-具有相同的子文件夾和文件結構集

[英]Diff two folders using python - having same set of subfolders and file structures

我試圖在python中編寫一個函數來比較兩個文件夾(具有完全相同的子目錄結構和文件列表)。

該文件夾必然包含.c .h .txt .cat .sys .pdb,但是主要集中在C和頭文件上。

此diff(folder1,folder2)的輸出應返回以下內容

  1. 在folder2中打印新添加的驅動程序文件(僅c和.h)

  2. 與文件夾1相比,在文件夾2中打印已刪除的驅動程序文件

(這可以通過兩個杠桿來循環將os.walk結果存儲在兩個列表中,然后減去它們)

  1. 我的挑戰:diff()函數應該開始比較所有子目錄中的文件,並且即使找到在folder2中修改過的一個(c或h)文件,也應該結束diff例程並返回FLAG = 1

例如。

folder1 \\ foo \\ bar \\ 1.c folder2 \\ foo \\ bar \\ 1.c->相同

folder1 \\ foo \\ car \\ 2.c folder2 \\ foo \\ car \\ 2.c->相同

folder1 \\ foo \\ dar \\ 13.c folder2 \\ foo \\ dar \\ 13.c->不同->返回標志= 1

folder1 \\ foo \\ far \\ 211.c folder2 \\ foo \\ far \\ 211.c->未比較

我試圖使用os.walk(path)函數來執行此操作,並將所有文件存儲在兩個單獨的列表中。 但我發現此位置中的多個文件非常長且復雜。

另外,如果有一種方法可以忽略perforce標頭,注釋和其他空格,那么它將增強我的腳本

任何建議,不勝感激

這是我要做什么的粗略概述:

  • 創建一個set()的folder1文件名folder1_set
  • os.walk()是您的朋友,加載folder1並開始瀏覽文件。
  • 對於每個文件,請打開它。 修改路徑以指向第二個文件夾,打開第二個文件並檢查是否相等
  • 將文件名添加到folder1_set
  • 最后,我們必須跟蹤folder2中可能缺少的文件。 在folder2上使用os.walk() ,可以保留另一個set()文件名folder2_set
  • folder1_set - folder2_set將為您提供folder1_set - folder2_set任何項目,而不是folder1_set - folder2_set ,反之亦然。

編輯1

  • 為了准備注釋,您可以逐行讀取文件,在該行上使用.strip()刪除任一端的空格,然后在剝離行的開頭檢查是否存在/*
  • 對於單行注釋,您還必須檢查*/是否出現在行尾,如果存在,則將其排除。
  • 對於多行注釋,您可以忽略所有行,直到在行尾遇到*/為止。
  • 這還有清除空白行(刪除所有空格)的好處。
  • 退房os.path.splitext以便在walk輕松找到文件擴展名。

您應該能夠使用Python的filecmp庫完成此操作。

編輯答案

通過@DennisNinj處理其他評論

謝謝,總有沒有包含.c和.h來進行文件比較? 每個文件夾中有20多種文件類型,每個文件夾中有1000多種文件? –丹尼斯·寧吉

@DennisNinj是的,有可能,只是比較棘手。 Filecmp.dircmp當前發布的版本不支持通配符或正則表達式匹配,因為其“忽略”和“隱藏”過濾器。 (已經提交了一個補丁來支持dircmp中的通配符。)因此,這意味着您必須手動進行過濾。

這是一個更新的示例,使您更接近要完成的任務。 注意 :請注意,由於需要在找到不同的C或頭文件后停止執行方法,因此可能無法在比較目錄中獲得每個“添加/刪除的驅動程序”的文件列表,因為它可能還沒有機會遍歷所有子目錄。

ccodedircomparison.py

import re
from filecmp import dircmp


def main():
    dcmp = dircmp("/Users/joeyoung/web/stackoverflow/dircomparison/test1", "/Users/joeyoung/web/stackoverflow/dircomparison/test2")
    if diffs_found(dcmp):
        print "FLAG = 1"


def diffs_found(dcmp):
    c_files_regex = re.compile(r".*\.[ch]$")
    deleted_drivers = []
    if len(dcmp.left_only) > 0:
        for left_only_file in dcmp.left_only:
            c_files_match = c_files_regex.match(left_only_file)
            if c_files_match:
                deleted_drivers.append(left_only_file)
        if len(deleted_drivers) > 0:
            print "Drivers deleted from {dirname}: [{deleted_drivers_list}]".format(dirname=dcmp.right, deleted_drivers_list=', '.join(deleted_drivers))
    added_drivers = []
    if len(dcmp.right_only) > 0:
        for right_only_file in dcmp.right_only:
            c_files_match = c_files_regex.match(right_only_file)
            if c_files_match:
                added_drivers.append(left_only_file)
        if len(added_drivers) > 0:
            print "Drivers added to {dirname}: [{added_drivers_list}]".format(dirname=dcmp.right, added_drivers_list=', '.join(dcmp.right_only))
    if len(dcmp.diff_files) > 0:
        differing_c_files = []
        for diff_file in dcmp.diff_files:
            c_files_match = c_files_regex.match(diff_file)
            if c_files_match:
                differing_c_files.append(diff_file)
        if len(differing_c_files) > 0:
            print "C files whose content differs ({dirname}): [{differing_c_files}]".format(dirname=dcmp.right, differing_c_files=', '.join(differing_c_files))
            return True
    for sub_dcmp in dcmp.subdirs.values():
        return diffs_found(sub_dcmp)
    return False

if __name__ == '__main__':
    main()

輸出示例

(.virtualenvs)macbook:dircomparison joeyoung$ python ccodedircomparison.py 
Drivers deleted from /Users/joeyoung/web/stackoverflow/dircomparison/test2/support: [thisismissingfromtest2.c]
Drivers added to /Users/joeyoung/web/stackoverflow/dircomparison/test2/support: [addedfile1.h]
C files whose content differs (/Users/joeyoung/web/stackoverflow/dircomparison/test2/support): [samefilenamedifftext1.h, samefilename1.c]
FLAG = 1

測試環境目錄結構

(.virtualenvs)macbook:dircomparison joeyoung$ tree test1 test2
test1
├── affected.test.js
├── blob.test.js
├── cache.test.js
├── constants.test.js
├── database_fail.test.js
├── each.test.js
├── exec.test.js
├── extension.test.js
├── fts-content.test.js
├── issue-108.test.js
├── map.test.js
├── named_columns.test.js
├── named_params.test.js
├── null_error.test.js
├── nw
│   ├── Makefile
│   ├── index.html
│   ├── package.json
│   ├── thisismissingfromtest2.c
│   └── thisismissingfromtest2.txt
├── open_close.test.js
├── other_objects.test.js
├── parallel_insert.test.js
├── prepare.test.js
├── profile.test.js
├── rerun.test.js
├── scheduling.test.js
├── serialization.test.js
├── support
│   ├── createdb.js
│   ├── elmo.png
│   ├── helper.js
│   ├── onlyintest1.txt
│   ├── prepare.db
│   ├── samefilename1.c
│   ├── samefilename1.txt
│   ├── samefilenamedifftext1.h
│   ├── samefilenamedsametext1.h
│   ├── script.sql
│   ├── thisismissingfromtest2.c
│   └── thisismissingfromtest2.txt
├── trace.test.js
└── unicode.test.js
test2
├── affected.test.js
├── blob.test.js
├── cache.test.js
├── constants.test.js
├── database_fail.test.js
├── each.test.js
├── exec.test.js
├── extension.test.js
├── fts-content.test.js
├── issue-108.test.js
├── map.test.js
├── named_columns.test.js
├── named_params.test.js
├── null_error.test.js
├── nw
│   ├── Makefile
│   ├── index.html
│   └── package.json
├── open_close.test.js
├── other_objects.test.js
├── parallel_insert.test.js
├── prepare.test.js
├── profile.test.js
├── rerun.test.js
├── scheduling.test.js
├── serialization.test.js
├── support
│   ├── addedfile1.h
│   ├── createdb.js
│   ├── elmo.png
│   ├── helper.js
│   ├── prepare.db
│   ├── samefilename1.c
│   ├── samefilename1.txt
│   ├── samefilenamedifftext1.h
│   ├── samefilenamedsametext1.h
│   └── script.sql
├── trace.test.js
└── unicode.test.js

編輯之前的原始答案

我的示例並沒有完全按照您的描述進行操作,但是此示例與filecmp.dircmp() 文檔之間應該有足夠的內容來入門。

dircomparison.py

from filecmp import dircmp

def main():
    dcmp = dircmp("/Users/joeyoung/web/stackoverflow/dircomparison/test1", "/Users/joeyoung/web/stackoverflow/dircomparison/test2")
    if diffs_found(dcmp):
        print "DIFFS FOUND!"
    else:
        print "NO DIFFS FOUND"


def diffs_found(dcmp):
    if len(dcmp.left_only) > 0:
        print dcmp.report_full_closure()
        return True
    elif len(dcmp.right_only) > 0:
        print dcmp.report_full_closure()
        return True
    else:
        for sub_dcmp in dcmp.subdirs.values():
            if diffs_found(sub_dcmp):
                return True
    return False

if __name__ == '__main__':
    main()

輸出示例

(.virtualenvs)macbook:dircomparison joeyoung$ python dircomparison.py 
diff /Users/joeyoung/web/stackoverflow/dircomparison/test1/support /Users/joeyoung/web/stackoverflow/dircomparison/test2/support
Only in /Users/joeyoung/web/stackoverflow/dircomparison/test1/support : ['onlyintest1.txt']
Identical files : ['createdb.js', 'elmo.png', 'helper.js', 'prepare.db', 'script.sql']
None
DIFFS FOUND!

實際的目錄結構因此您可以看到我的測試環境是什么樣的。

(.virtualenvs)macbook:dircomparison joeyoung$ tree test1
test1
├── affected.test.js
├── blob.test.js
├── cache.test.js
├── constants.test.js
├── database_fail.test.js
├── each.test.js
├── exec.test.js
├── extension.test.js
├── fts-content.test.js
├── issue-108.test.js
├── map.test.js
├── named_columns.test.js
├── named_params.test.js
├── null_error.test.js
├── nw
│   ├── Makefile
│   ├── index.html
│   └── package.json
├── open_close.test.js
├── other_objects.test.js
├── parallel_insert.test.js
├── prepare.test.js
├── profile.test.js
├── rerun.test.js
├── scheduling.test.js
├── serialization.test.js
├── support
│   ├── createdb.js
│   ├── elmo.png
│   ├── helper.js
│   ├── onlyintest1.txt
│   ├── prepare.db
│   └── script.sql
├── trace.test.js
└── unicode.test.js

2 directories, 33 files
(.virtualenvs)macbook:dircomparison joeyoung$ tree test2
test2
├── affected.test.js
├── blob.test.js
├── cache.test.js
├── constants.test.js
├── database_fail.test.js
├── each.test.js
├── exec.test.js
├── extension.test.js
├── fts-content.test.js
├── issue-108.test.js
├── map.test.js
├── named_columns.test.js
├── named_params.test.js
├── null_error.test.js
├── nw
│   ├── Makefile
│   ├── index.html
│   └── package.json
├── open_close.test.js
├── other_objects.test.js
├── parallel_insert.test.js
├── prepare.test.js
├── profile.test.js
├── rerun.test.js
├── scheduling.test.js
├── serialization.test.js
├── support
│   ├── createdb.js
│   ├── elmo.png
│   ├── helper.js
│   ├── prepare.db
│   └── script.sql
├── trace.test.js
└── unicode.test.js

2 directories, 32 files

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM