さつまろぐ

CAEとかプログラムとか、出来たことの記録など、誰かのお役に立てれば幸い。

Pythonで遊ぶ ファイル一覧の取得

ファイルを色々操作するために、ファイルの一覧を取得したい、 というときはglobを使うらしいのでメモ。

前提

下記のようなファイル構造であるとする。

. ─┬─ text01.txt
   ├─ text02.txt
   ├─ Excel01.xlsx
   ├─ Excel02.xlsx
   ├─ pdf01.pdf
   ├─ pdf02.pdf
   ├─ folder01 ───┬─ folder02 ─── text05.txt
   │              ├─ text03.txt
   │              └─ text04.txt
   └─ folder03 ───── text06.txt

以降 globを使うのでインポートしておく。

>>> import glob

一覧の取得

glob.glob( )でファイル名を取得する。

>>> files = glob.glob('*')  #全ファイル名を取得
>>> print(files)
['Excel01.xlsx', 'Excel02.xlsx', 'folder01', 'folder03', 'pdf01.pdf', 'pdf02.pdf', 'text01.txt', 'text02.txt']

確かにファイル名は取得できたが、フォルダも混ざっている。そしてサブフォルダ内のファイルは取得できていない。 そこで、*.txtでテキストファイルだけ取得するようにしてみる。

>>> files = glob.glob('*.txt') #テキストファイルだけを取得
>>> print(files)
['text01.txt', 'text02.txt']

テキストファイルのみ取得できた。次にフォルダ内のテキストファイルを取得してみる。

>>> files = glob.glob('*/*.txt') #フォルダ内のファイルを取得。ただしその階層のみ
>>> print(files)
['folder01\\text03.txt', 'folder01\\text04.txt', 'folder03\\text06.txt']

フォルダ内のテキストが取得できたが、*/*.txtの構造(カレントディレクトリにあるフォルダ内(1階層のみ))のテキストファイルしか取得できていない。

このようなときは、**/*.txtrecursive=Trueを指定することで、フォルダ階層を再帰的に探索してくれる。

>>> files = glob.glob('**/*.txt', recursive=True)    #現在のフォルダを含むすべてのサブフォルダからフ ァイルを取得
>>> print(files)
['text01.txt', 'text02.txt', 'folder01\\text03.txt', 'folder01\\text04.txt', 'folder01\\folder02\\text05.txt', 'folder03\\text06.txt']

これでサブフォルダを含むすべてのフォルダからファイル名を取得することができた。

ファイル構造を含まないファイル名

上の結果では、取得したファイル名にパスを含んでいる。パスが不要な場合、パスを取り除く処理をする。 ここではsplit( )basename( )を使うので、osをインポートしておく。

>>> import os

split( )でパスとファイル名を分けることができる。結果は長さ2のタプルで返ってくる。

>>> print(os.path.split(files[0]))
('', 'text01.txt')
>>> print(os.path.split(files[2]))
('folder01', 'text03.txt')
>>> print(os.path.split(files[4]))
('folder01\\folder02', 'text05.txt')

パスの情報が必要なければ、basename( )でファイル名だけ取得することができる。

>>> print(os.path.basename(files[0]))    #basenameはファイル名だけを出力する
text01.txt
>>> print(os.path.basename(files[2]))
text03.txt
>>> print(os.path.basename(files[4]))
text05.txt

なおsplit( )の結果はタプルなので、インデックス指定すればbasename( )と同じ結果を出せる。

>>> print(os.path.split(files[4])[1])
text05.txt

パスとファイル名の分離は、for文を使って各ファイル名ごとに行う。

>>> files = glob.glob('**/*.txt', recursive=True)    
>>> name = [os.path.basename(f) for f in files]  #各ファイル名にbasename( )をかける
>>> print(name)
['text01.txt', 'text02.txt', 'text03.txt', 'text04.txt', 'text05.txt', 'text06.txt']

最終的にサブフォルダを含めたファイル名だけを取得することができた。 問題はこのファイルに何をするか。

広告