2016-11-04 2 views
2

내가 스캔하고자하는 구조화 된 파트와 (스캔하고 싶지 않은) 비 구조화 된 파트가있는 수백 또는 GB의 데이터가있는 디렉토리를 스캔해야합니다.Python os.walk 복잡한 디렉토리 기준

os.walk 함수를 읽어 보면 집합에서 일련의 기준을 사용하여 특정 디렉토리 이름이나 패턴을 제외하거나 포함 할 수 있습니다. 두 개의 유용한 디렉토리, '디렉터리 A'와 '디렉터리가 상상 루트 디렉토리에서

: 내가 예를 들어, 디렉토리에 특정 레벨 당 기준을 포함 ​​/ 제외 추가해야이 특정 스캔

B '및 유용하지 않은 휴지통 디렉토리'휴지통 '으로 구분됩니다. Dir A에는 'Subdir A1'과 'Subdir A2'라는 유용한 하위 디렉토리와 유용하지 않은 'SubdirA Trash'디렉토리가 있습니다. 그런 다음 Dir B에는 유용한 Subdir B1과 Subdir B2와 함께 유용한 'SubdirB Trash' 하위 디렉토리. 같은 같습니다

Example Directory

내가, 각 레벨에 대한 특정 기준 목록이이 같은 필요

level1DirectoryCriteria = 세트 ("디렉터리 A"를, "디렉터리 B")

level2DirectoryCriteria = 세트 ("하위 디렉터리 A1", "하위 디렉터리 A2", "하위 디렉터리 B1", "B2 서브 디렉토리")

내가 이것을 수행 할 수있는 유일한 방법은 많은 변수와 불안정성의 높은 위험성을 가진 복잡하고 긴 코드를 사용하는 것은 분명히 비 pyonic입니다. 누구든지이 문제를 해결하는 방법에 대한 아이디어가 있습니까? 성공하면 한 번에 몇 시간 씩 코드 실행 시간을 절약 할 수 있습니다.

답변

2

당신은 이런 식으로 뭔가를 시도 할 수 :

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 
+0

이 보인다 :

현재 위치 찾기() 메소드에 대한 자세한 정보를 찾을 수 있습니다. – user3535074

+1

해결책은 여기에서 왔습니다! – user3535074

1

하지 os.walk하지만 단지 제안에 관한 직접적인 대답 : 당신은 어쨌든 디렉토리를 검색하고, 당신은 분명히 다른 디렉토리에서 쓰레기 디렉토리를 알고 있기 때문에, 당신은 또한 쓰레기 디렉토리에 더미 파일을 배치 할 수 있습니다 skip_this_dir 또는 무엇인가. 디렉토리를 반복하고 파일 목록을 만들 때 if 'skip_this_dir' in filenames: continue;과 같은 파일 skip_this_dir이 있는지 확인하고 다음 반복을 계속합니다.

이것은 os.walk 매개 변수를 사용하지 않아도되지만 많은 수의 조건문과 포함/제외 목록이 포함 된 '지저분한'코드를 작성하지 않아도 프로그래밍 작업을 조금 더 쉽게 관리 할 수 ​​있습니다. 또한 코드를 변경할 필요가 없으므로 스크립트를 재사용하기 쉽습니다. 건너 뛸 필요가있는 디렉토리에 더미 파일을 배치하기 만하면됩니다.

+0

좋은 생각이지만 스캔하고 싶지 않은 dir에 건너 뛰기 플래그를 추가하는 데 오랜 시간이 걸릴 수 있습니다. 내가 스캔하고자하는 dir을 말하기가 훨씬 쉬우 며, 앞으로 어떤 것을 추가해야한다면 비교적 쉽습니다. 당신은 복잡한 코드를 피하는 것에 대해 옳습니다 - 나는 당신의 제안을 염두에 둡니다. – user3535074

+0

그래, 만약 당신이 쓰레기 디렉토리가 많다면 그것들을 모두 플래그하는 것이 번거로울 수있다. 또한 처리하려는 디렉토리에 플래그를 지정하여 추론을 전환 할 수도 있지만 처리해야하는 디렉토리가 많을 것으로 추정합니다. – TBZ92

0

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]] 
0

OP와 비슷한 해결책을 찾고있었습니다. 나는 하위 폴더를 스캔해야하고 '쓰레기'라는 폴더가있는 폴더를 제외해야했습니다. 내 해결책은 find() 문자열 문자열을 사용하는 것이 었습니다. 사용 방법은 다음과 같습니다.

for (dirpath, dirnames, filenames) in os.walk(your_path): 
    if dirpath.find('trash') > 0: 
     pass 
    elif dirpath.find('trash)') < 0: 
     do_stuff 

'trash'가 발견되면 색인 번호가 반환됩니다. 그렇지 않으면 find()는 -1을 반환합니다. 나는 그것을 밖으로 시도하고 당신에게 되돌아 올 것이다 promising- https://www.tutorialspoint.com/python/string_find.htm