こんにちは!少しずつ暑くなってきましたね!夏も近いです。
さっそくですが、タイトルが何を言っているのかを説明します。
例えば、ある「親フォルダ」の中にいくつかの種類のファイル (エクセルファイルとか画像ファイルとか) と「子フォルダ」も何個かあって、その「子フォルダ」の中にもいくつかのファイルがあって、さらにさらにその「子フォルダ」の中にも「孫フォルダ」があって、さらにさらにさらに「孫フォルダ」の中に「曾孫フォルダ」が・・・「玄孫フォルダ」が・・・・となっている状況で、エクセルファイルだけを取り出して Python で処理したい!
みたいな状況ってよくあると思います。そんな時のためのまとめもです。
glob を使う
今回は上のような状況を考えます。
コマンドプロンプトの TREE コマンドで確認すると以下のようになっています。
このとき、親フォルダを選択するとその中のサブフォルダ (子フォルダ、孫フォルダ) も含めてすべてのエクセルファイル (.xlsx) を取得したいと思います。
標準ライブラリ glob の glob 関数を使って以下のようにするとOKです。
glob.glob(“親フォルダ/**/*.xlsx”, recursive=True)
ポイントはアスタリスク2つ (**) と recursive=True です。
この glob 関数を実行すると親フォルダ内のエクセルファイルのパスのリストが返ってきます。
上記説明では単に親フォルダと書いていますが、実行する際にはソースコードと同じ場所 (ディレクトリ) に親フォルダがない、パスが通っていないなどの場所には普通に親フォルダまでの絶対パスを書いてください。もちろん相対パスでもオッケーです。
ただ、実際に使うときは以下のように親フォルダのパスを別に保持しておいて、os.path.join 関数で結合してパスを作ると分かりやすいと思います。
glob.glob(os.path.join(basedir, “**/*.xlsx”), recursive=True)
今回の例だとbasedir の部分に親フォルダのパスをいれます。
ちょっと実用ソースコード
実際に使うときを想定して、親フォルダをダイアログで選択するバージョンのソースコードです。
ここでは対象ファイルを取得して、それをすべて表示してます。
import os
import glob
def get_filepath_list():
# フォルダ選択ダイアログ関連
root = tk.Tk()
root.withdraw()
basedir = tkinter.filedialog.askdirectory(title="フォルダを選択")
# フォルダ内 (サブフォルダも含めて) の対象ファイルを取得
filepath_list = glob.glob(os.path.join(basedir, "**/*.xlsx"), recursive=True)
return filepath_list
def main():
for var in get_filepath_list():
print(var)
if __name__ == "__main__":
main()
ダイアログで選択したフォルダを basedir に格納しています。
これを実行して、ダイアログで「親フォルダ」を選択すると、、、
しっかりとエクセルファイルだけ取得できています!
ダイアログで「親フォルダ」ではなく「子フォルダ2」を選ぶと、
子フォルダ2の中にあるエクセルファイルだけゲットできています!
もちろんエクセルだけではありません。
画像ファイルでもオッケーです。
glob.glob(os.path.join(basedir, “**/*.png”), recursive=True)
として実行すると、
ちゃんと画像ファイル (.png) が取得できています。
取得したいファイルの指定方法は拡張子でなくともオッケーです。
例えばファイル名に “-1” が入っているものが欲しくなったときは
glob.glob(os.path.join(basedir, “**/*-1*”), recursive=True)
とすればいけます。これで実行すると、
“1-1” や “2-1” のようにファイル名に “-1” が含まれるものだけが取得できています。
コメント