iT邦幫忙

0

Python 搜尋子目錄下檔案+篩選條件 walk+fnmatch

Python os.walk 找檔案很容易,可是 天坑 也不少。逐行註解、測試,才不會搞迷糊了。
延伸上一篇的基本寫法,今天把它模組化(函數化) Source code download
套件 lib
from os.path import join
import os, fnmatch
兩個函數:一個找所有檔案、一個找特定檔案。
findAll()

#--- 尋找某目錄(包括子目錄)下全部檔案
#--- 傳入參數 nPath目錄名稱 / txtFile 將結果存檔 
#--- 傳回一個 list fList 全部的檔案名稱 
def findAll( nPath,txtFile ):
    ''' os.walk 遞迴找出所有檔案
    fTree 傳回一個tuple,包含三元素
      dirs     該層的 path
      subdirs  該層的 目錄s
      files    該層的 檔案s
    topdown = True 從上向下找 '''
    fTree = os.walk( nPath, topdown=True )
    dList = []  # 某檔案的 path
    sList = []  # 該檔案同一層的 目錄
    fList = []  # 該檔案的fullPathName 
    
    # 逐層從上向下
    for dirs, subdirs, files in fTree:
        for f in files: 
            # 添加入 list
            dList.append(dirs)
            sList.append(subdirs)
            # dirs+f 組合成 檔案的fullpathname 
            fullpath = join(dirs,f)
            fList.append(fullpath)
    '''       
    # 此時的 dirs, subdirs,files 只是最後一個folder的搜尋結果
    # 並不是全部檔案的 path,可將他們印出來看看
      print(f'len(dirs): {len(dirs)}')
      print(f'len(subdirs): {len(subdirs)}')
      print(f'len(files): {len(files)}')
    '''

    # 檢視成果        
    print(f'dir count目錄數量 : {len(dList)}')
    print(f'sList count: {len(sList)}')
    print(f'file count : {len(fList)}')

    # 印出來看看
    for f in range(len(fList)):
        print(dList[f],sList[f],fList[f])

    # 把結果存檔,以供驗證
    txt = open(txtFile,'w',encoding='utf-8') 
    for f in range(len(fList)):
        print(f'{dList[f]}  {sList[f]} {fList[f]}',file=txt)
    txt.close()
    
    return fList  # 傳回這個list

findSome()

#--- 找某些類型的檔案
#--- 傳入參數 nPath目錄名稱 / fTypes檔案類型 / txtFile 將結果存檔 
#--- 傳回一個 list allFiles 符合的檔案名稱 
def findSome(nPath, fTypes, txtFile):
    allFiles = []
    for dirs, subdirs, files in os.walk( nPath ):
        for extension in ( tuple(fTypes) ):
            for filename in fnmatch.filter(files, extension):
                filepath = os.path.join(dirs, filename)		
                if os.path.isfile( filepath ):
                    allFiles.append(filepath)
                    print(filepath)
    
    # 把結果存檔,以供驗證
    f = open( txtFile,'w',encoding='utf-8' ) 
    for i in allFiles:
        print(f'{i}',file=f)
    f.close()
    
    return allFiles  # 傳回這個list

叫用的方法

#--- 流程 主軸 -----
pathHere = os.getcwd() # 當前目錄位置

# 指定搜尋之目錄 (或者預設為當前目錄)
path = input('從哪個資料夾 開始搜尋 ? ') or pathHere
print(f'搜尋資料夾: {path} (包含子目錄)所有檔案')
#--- call the function findAll()
txt1 = 'resultAll.txt'
retAll = findAll(path, txt1)
print(f'搜尋完成,全部檔案: {len(retAll)} 個')

#--- call the function findSome()
# 要篩選的檔案類型
filetypes = ['*.jpg', '*.png', '*.doc']  
txt2 = 'resultSome.txt'
print('os.walk + filter 使用fnmatch的寫法')
retSome = findSome(path, filetypes, txt2)
print(f'搜尋完成,符合的檔案: {len(retSome)} 個')

寫完了,有沒有衝動,想把它改成視窗介面?


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言