[英]Python os.walk complex directory criteria
我需要掃描包含數百個或GB數據的目錄,該數據具有結構化部分(我要掃描)和非結構化部分(我不想掃描)。
通過閱讀os.walk函數,我發現我可以在一組標准中使用一組標准來排除或包括某些目錄名稱或模式。
對於此特定掃描,我將需要在目錄中按級別添加特定的包含/排除條件,例如:
在根目錄中,假設有兩個有用的目錄“ Dir A”和“ Dir B”,以及一個無用的垃圾箱目錄“ Trash”。 在目錄A中有兩個有用的子目錄“ Subdir A1”和“ Subdir A2”,以及一個無用的“ SubdirA Trash”目錄,然后在目錄B中有兩個有用的子目錄Subdir B1和Subdir B2以及一個無用的“ SubdirB Trash”子目錄。 看起來像這樣:
我需要每個級別都有一個特定的條件列表,如下所示:
level1DirectoryCriteria = set(“ Dir A”,“ Dir B”)
level2DirectoryCriteria = set(“ Subdir A1”,“ Subdir A2”,“ Subdir B1”,“ Subdir B2”)
我能想到的唯一方法顯然是使用復雜且冗長的代碼(具有大量變量且不穩定的風險很高)使用非Python語言。 是否有人對如何解決此問題有任何想法? 如果成功,則可以一次節省幾個小時的代碼運行時間。
您可以嘗試這樣的事情:
to_scan = {'set', 'of', 'good', 'directories'}
for dirpath, dirnames, filenames in os.walk(root):
dirnames[:] = [d for d in dirnames if d in to_scan]
#whatever you wanted to do in this directory
此解決方案很簡單,如果要掃描具有特定名稱的目錄(如果它們出現在一個目錄中而不是另一個目錄中),則失敗。 另一個選擇是將目錄名稱映射到白名單或黑名單目錄的列表或集合的字典。
編輯:我們可以使用dirpath.count(os.path.sep)
來確定深度。
root_depth = root.count(os.path.sep) #subtract this from all depths to normalize root to 0
sets_by_level = [{'root', 'level'}, {'one', 'deep'}]
for dirpath, dirnames, filenames in os.walk(root):
depth = dirpath.count(os.path.sep) - root_depth
dirnames[:] = [d for d in dirnames if d in sets_by_level[depth]]
#process this directory
不是有關os.walk
的直接答案,而是一個建議:由於無論如何都在掃描目錄,並且您顯然知道其他目錄的回收站目錄,因此您還可以在回收站目錄skip_this_dir
或其他內容中放置一個虛擬文件。 遍歷目錄並創建文件列表時,請檢查skip_this_dir
文件是否存在, skip_this_dir
文件if 'skip_this_dir' in filenames: continue;
並繼續進行下一個迭代。
這可能不涉及使用os.walk
參數,但這確實使編程任務更易於管理,而無需編寫大量帶有大量條件和包含/排除列表的“混亂”代碼。 由於不需要更改任何代碼,只需將虛擬文件放在需要跳過的目錄中,這也使腳本更易於重用。
通過使用root.count(os.path.sep),我可以在結構的每個級別上創建有關包含/排除內容的特定說明。 看起來像這樣:
import os
root_depth = root.count(os.path.sep) #subtract this from all depths to normalize root to 0
directoriesToIncludedByLevel = [{"criteriaString","criteriaString","criteriaString","criteriaString"},#Level 0
{"criteriaString","criteriaString","criteriaString" },#Level 1
{},#Level 2
]
directoriesToExcludedByLevel = [{}, #Level 0
{}, #Level 1
{"criteriaString"}, #Level 2
]
for dirpath, dirnames, filenames in os.walk(root):
depth = dirpath.count(os.path.sep) - root_depth
# Here we create the dirnames path depending on whether we use the directoriesToIncludedByLevel or the directoriesToExcludedByLevel
if depth == 2: #Where we define which directories to exclude
dirnames[:] = [d for d in dirnames if d not in directoriesToExcludedByLevel[depth]]
elif depth < 2 : #Where we define which directories to INclude
dirnames[:] = [d for d in dirnames if d in directoriesToIncludedByLevel[depth]]
我一直在尋找類似於OP的解決方案。 我需要掃描子文件夾,並且需要排除所有帶有標記為“垃圾箱”的文件夾。 我的解決方案是使用字符串find()方法。 這是我的用法:
for (dirpath, dirnames, filenames) in os.walk(your_path):
if dirpath.find('trash') > 0:
pass
elif dirpath.find('trash)') < 0:
do_stuff
如果找到“垃圾箱”,它將返回索引號。 否則,find()將返回-1。
您可以在這里找到有關find()方法的更多信息: https : //www.tutorialspoint.com/python/string_find.htm
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.