2012年4月17日

Python:使用os.walk() 遞迴印出資料夾中所有目錄及檔名


 
有時候我們會需要在 linux 中列出某個資料夾底下所有的目錄和檔名,
因為這有點像要某個人進每一個資料夾去看看裡面有什麼東西,
姑且就讓我們叫這個走訪的行為叫 walk 吧。(下面那個是Johnnie Walker喔~~~ XD)

圖片來源:http://www.wememap.com/blogs/1619120304

如果想要對資料夾的內容有視覺化的展現,
可以使用 tree 這個指令來列出資料夾底下的結構,
下的指令和顯示的結果如下:
[root@localhost demo]# tree /python/demo/
/python/demo/
|-- os_walk.py
|-- root
|   |-- 1file
|   |-- 2subDir
|   |   |-- 21file
|   |   |-- 22subDir
|   |   |   `-- 221file
|   |   `-- 23file
|   |-- 3file
|   `-- 3subDir
|       `-- 31file
`-- walk.py

4 directories, 8 files

由上面我們可以看得出來 root 底下有一些資料夾和檔案,
我已經特別用不同的顏色標示過了,藍色是資料夾,紅色是檔案,
而紫色的則是這篇要說明的 python 檔。

雖然已經可以顯示資料夾內部的檔案結構了,
但這次我想要的並不是要視覺化的結果,
我只想要底下所有檔案的完整絕對路徑就好。
本來想用 bash 之類的 script 寫,但因為基礎不足,
且想說用 script 來做字串處理感覺只會給自己帶來更多麻煩,
所以就想說來研究一下強大的 python。

結果顯示我的選擇是對的,
短短幾行就能達成我的目的,且 python 的程式碼也能在 windows 上運作。
以下是能達成我目的的 Python walk.py 原始碼:
import os

for dirPath, dirNames, fileNames in os.walk("/python/demo/"):
    print dirPath
    for f in fileNames:
        print os.path.join(dirPath, f)

Python 執行結果:
[root@localhost demo]# python walk.py 
/python/demo/
/python/demo/walk.py
/python/demo/os_walk.py
/python/demo/root
/python/demo/root/1file
/python/demo/root/3file
/python/demo/root/3subDir
/python/demo/root/3subDir/31file
/python/demo/root/2subDir
/python/demo/root/2subDir/23file
/python/demo/root/2subDir/21file
/python/demo/root/2subDir/22subDir
/python/demo/root/2subDir/22subDir/221file

和上面一樣用不同的顏色標註,
短短幾行程式就能達成我們的目的了,是不是很簡單呢?

為了了解整個實作,我們特地先用比較簡單的方式來了解,
這次程式碼中用到的關鍵是 os.walk(),
我們先把程式碼成簡化成以下這樣,來看一下回傳的結果。

Python os_walk.py 原始碼:
import os

for response in os.walk("/python/demo/"):
    print response

Python os_walk.py 執行結果:
[root@localhost demo]# python os_walk.py 
('/python/demo/', ['root'], ['walk.py', 'os_walk.py'])
('/python/demo/root', ['3subDir', '2subDir'], ['1file', '3file'])
('/python/demo/root/3subDir', [], ['31file'])
('/python/demo/root/2subDir', ['22subDir'], ['23file', '21file'])
('/python/demo/root/2subDir/22subDir', [], ['221file'])

由 os_walk.py 的執行結果我們可以發現,
os.walk() 回傳的結果分為很多行,每一行有其固定格式,
我已經將關鍵的部份用不同顏色標出來了,
而這個格式套用在 walk.py 中,就會是關鍵的一行:
for dirPath, dirNames, fileNames in os.walk("/python/demo/"):

大家可以把每一行的顏色對應到上面的程式碼中,
os.walk() 這個 function 回傳時每行可以得到一個三元的 tupple,
其中第一個 dirPath 是這行啟始路徑,
第二個 dirNames 是一個 list,裡面包含了 dirPath 下所有的資料夾名稱,
而第三個 fileNames 也是一個 list,包含了 dirPath 下所有的檔案名稱。
所以我們利用 for 走過 os.walk() 所有的 dirPath
並且利用底下的 for 把 fileNames 中所有的 f 拿出來,
再以 os.path.join(dirPath, f) 把資料夾路徑和檔名串接起來,
組合成完整路徑後輸出,就達成我們的目的了。

經過這樣的說明,是不是對 os.walk() 的運作方式完全理解了呢?
應該還算簡單不會很難理解吧 :p

關鍵字:Python, 遞迴, 處理, 路徑, 檔案, 資料夾, 使用, os.walk(), 印出, 所有, 目錄, 檔名, 子目錄, 子資料夾, 下面, 走訪
參考資料:


更多精選推薦文章