1. 程式人生 > >用 Python 定位特定類型文件

用 Python 定位特定類型文件

dsw mat end 區分大小寫 name 測試 串匹配 查找 字符

定位特定文件

定位特定的文件,可以使用 fnmatch 以及 glob 這兩個標準庫,我們下面來分別看一下。

1. 使用 fnmatch 標準庫

一般的話我們想要查找特定類型的文件,可以通過字符串的前綴匹配和後綴匹配來查找,具體實例如下所示:

>>> import os
>>> [txt for txt in os.listdir(.) if txt.endswith(.txt)]
[b.txt, a.txt]

其實大部分的情況下這種用字符串匹配的方法來查找文件就足夠可以滿足需要,如果有些情況下需要更加靈活一點的字符串匹配,就可以使用 fnmatch 庫,這是一個專門用來進行文件名匹配的庫,支持使用通配符來進行文字匹配(比如‘*‘,‘?‘等)。

fnmatch 這個庫很簡單,只有 4 個函數:fnmatch,fnmatchcase,filter,translate:

  • fnmatch:判斷文件名是否符合特定的模式;

  • fnmatchcase:判斷文件名是否符合特定的模式(不區分大小寫);

  • filter:返回輸入列表中,符合特定模式的文件名列表;

  • translate:將通配符模式轉換成正則表達式。

上面 4 個最常用是它的同名函數 fnmatch ,我的當前目錄下有 4 個文件,分別是:a.txt,b.txt,c.py,test.py,下面我就用 fnmatch 函數來對當前目錄下的這 4 個文件進行匹配性測試,具體請看下面代碼:

>>> import os
>>> import fnmatch
>>> os.listdir(.)
[test.py, c.py, b.txt, a.txt]
>>> [txt for txt in os.listdir(.) if fnmatch.fnmatch(txt, *.txt)]
[b.txt, a.txt]
>>> [file for file in os.listdir(.) if fnmatch.fnmatch(file, [a-c]*)]
[
c.py, b.txt, a.txt] >>> [file for file in os.listdir(.) if fnmatch.fnmatch(file, [!a-c]*)] [test.py]

fnmatchcase 函數與 fnmatch 函數幾乎一樣,只是在匹配的時候會忽略大小寫字母;filter 函數與 fnmatch 比較類似,區別在於fnmatch 一次只對一個文件名匹配,而 filter 一次可以對多個文件名進行匹配判斷,下面我們就再來看一下 filter 的用法:

>>> import os
>>> import fnmatch
>>> file = os.listdir(.)
>>> file
[test.py, c.py, b.txt, a.txt]
>>> fnmatch.filter(file, [a-c]*)
[c.py, b.txt, a.txt]
>>> fnmatch.filter(file, [!a-c]*)
[test.py]

2.使用 glob 定位

我們在上面介紹的獲取特定類型的文件列表,首先是通過 os.listdir 獲取全部的文件列表,然後通過字符串匹配或者使用 fnmatch 進行文件名模式匹配來定位,習慣了 Python 的簡潔優雅,這多出來的一步總覺得哪裏怪怪的,好在我現在知道了 glob。

glob 的作用相當於 os.listdir + fnmatch 的組合,使用 glob 以後,就不需要用 os.listdir 獲取文件列表,直接通過模式匹配就可以解決了,具體操作如下所示:

>>> import glob
>>> glob.glob(*.txt)
[b.txt, a.txt]
>>> glob.glob([a-c]*)
[c.py, b.txt, a.txt]
>>> glob.glob([!a-c]*)
[test.py]

可以看到,Python 真的非常的靈活,光是定位目錄下特定的文件類型我就已經介紹了 3 種方式,一般情況下就用字符串匹配就可以解決,如果需要更加靈活一點的的,可以使用 fnmatch 和 glob。

遍歷目錄樹

再上一節中我們都是查找某個目錄下的文件然後通過匹配去定位自己需要的文件類型。但是在實際的應用過程中我們更可能遇到的是某個目錄及其子目錄下的所有文件。比如查找某個目錄及其子目錄下所有的 txt 文件等等,對於這類的需求,我們可以使用 os 模塊下的「walk」函數。walk 函數遍歷某個目錄及其子目錄,對於每一個目錄,walk 返回一個三元組,依次是「當前目錄」,「當前目錄下的子目錄」,「當前目錄下的文件列表」。

下面我們來演示一下 os.walk 函數的用法,做一個小的練習,來遍歷一下 /root/rocky0429 目錄及其子目錄下的所有 txt 和 圖片文件:

import os
import fnmatch

search = [*.txt, *.jpg, *.jpeg]
res = []

for root, dirnames, filenames in os.walk(os.path.expanduser(~/rocky0429)):
   for extension in search:
       for filename in fnmatch.filter(filenames, extension):
           res.append(os.path.join(root,filename))

       print(res)

用 Python 定位特定類型文件