本サイトにはPRが含まれています

Pythonでフォルダ内の指定したファイルをサブフォルダ内も含めて取得するときのまとめも

フォルダ内のファイル取得アイキャッチ画像 プログラミング

こんにちは!少しずつ暑くなってきましたね!夏も近いです。

さっそくですが、タイトルが何を言っているのかを説明します。

例えば、ある「親フォルダ」の中にいくつかの種類のファイル (エクセルファイルとか画像ファイルとか) と「子フォルダ」も何個かあって、その「子フォルダ」の中にもいくつかのファイルがあって、さらにさらにその「子フォルダ」の中にも「孫フォルダ」があって、さらにさらにさらに「孫フォルダ」の中に「曾孫フォルダ」が・・・「玄孫フォルダ」が・・・・となっている状況で、エクセルファイルだけを取り出して Python で処理したい!

みたいな状況ってよくあると思います。そんな時のためのまとめもです。

スポンサーリンク

glob を使う

今回の例のフォルダとファイルの状況の絵

今回は上のような状況を考えます。

コマンドプロンプトの TREE コマンドで確認すると以下のようになっています。

今回のフォルダとファイルの状況をtreeコマンドで確認した画像
コマンドプロンプトの 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を選択した場合の結果

子フォルダ2の中にあるエクセルファイルだけゲットできています!

もちろんエクセルだけではありません。

画像ファイルでもオッケーです。

glob.glob(os.path.join(basedir, “**/*.png”), recursive=True)

として実行すると、

画像ファイルを取得したときの結果

ちゃんと画像ファイル (.png) が取得できています。

取得したいファイルの指定方法は拡張子でなくともオッケーです。

例えばファイル名に “-1” が入っているものが欲しくなったときは

glob.glob(os.path.join(basedir, “**/*-1*”), recursive=True)

とすればいけます。これで実行すると、

ファイル名に1-が入っているものを取得するときの結果

“1-1” や “2-1” のようにファイル名に “-1” が含まれるものだけが取得できています。

コメント

タイトルとURLをコピーしました