Python|できるだけ短いコードでファイル一覧を取得する。

  • Pythonで指定フォルダの下層のファイル一覧を取得する。
  • 再帰的にサブフォルダの配下のファイルも取得
  • glob一発でファイル一覧を取得すると順番がいまいちなので解決策
  • 「フォルダ一覧を取得」→「ファイル一覧を取得」と二段階にするとイメージ通りになった。

Pythonでファイル一覧を取得する際に詰まったので備忘録。

目的

最終的にはpowershellの「tree /f」みたいなのをhtml出力して、大量のファイルを見やすく整理したい。そのための第一段階として、指定フォルダ内のファイル一覧を取得する。

C:.
└─ParentDirectoryFile1.txtFile2.txtFile3.txt
    │
    ├─ChildrenDirectory1File1.txtFile2.txtFile3.txt
    │
    └─ChildrenDirectory2
            File1.txt
            File2.txt
            File3.txtCode language: CSS (css)

こんな感じのツリー構造をhtml出力したい

ファイル一覧取得

まず単純にファイル一覧を取得するコードを探してみた。pythonにはglob関数というものがあるので、これを使うと簡単にファイル一覧を取得できそう。

この記事を書いてある内容をそのまま使ってみる。フォルダ構成は、下のように単純に一つのフォルダにスクリプトとフォルダを入れておく。スクリプトはたったの一行だけ「files = [p for p in glob(‘./files/**’,recursive=True) if os.path.isfile(p)]」

import os
from glob import glob
files = [p for p in glob('./files/**',recursive=True) if os.path.isfile(p)]
print('===================files======================')
for file in files:
    print(file)
print('=============================================')

出力結果はこのようになった。

出力結果
===================files======================
./files\ParentDirectory\ChildrenDirectory1\File1.txt
./files\ParentDirectory\ChildrenDirectory1\File2.txt
./files\ParentDirectory\ChildrenDirectory1\File3.txt
./files\ParentDirectory\ChildrenDirectory2\File1.txt
./files\ParentDirectory\ChildrenDirectory2\File2.txt
./files\ParentDirectory\ChildrenDirectory2\File3.txt
./files\ParentDirectory\File1.txt
./files\ParentDirectory\File2.txt
./files\ParentDirectory\File3.txt
====================================================

ちゃんと一覧は取得できているが、親ディレクトリ配下のファイルが下にきて、子ディレクトリ配下のファイルが上にきてしまった。目標にしているツリー構造っぽいものを作るにはいまいち。

ファイル名をいろいろ変えて検証してみる。ファイル名を以下のように変更してみた。

filesフォルダ内のフォルダ構造
=====================================================
C:.
└─ParentDirectory
    │  Aile1.txt
    │  File2.txt
    │  File3.txt
    │
    ├─ChildrenDirectory1
    │      Aile1.txt
    │      File2.txt
    │      File3.txt
    │
    └─ChildrenDirectory2
            Aile1.txt
            File2.txt
            File3.txt
===========================================================

この状態でスクリプトを動かした出力結果は以下の通り。


===================files======================
./files\ParentDirectory\Aile1.txt
./files\ParentDirectory\ChildrenDirectory1\Aile1.txt
./files\ParentDirectory\ChildrenDirectory1\File2.txt
./files\ParentDirectory\ChildrenDirectory1\File3.txt
./files\ParentDirectory\ChildrenDirectory2\Aile1.txt
./files\ParentDirectory\ChildrenDirectory2\File2.txt
./files\ParentDirectory\ChildrenDirectory2\File3.txt
./files\ParentDirectory\File2.txt
./files\ParentDirectory\File3.txt
====================================================

順番がさらにおかしくなってしまった。どうやらフルパスの名前順になっている。

順番を整えるために改良

一行のスクリプトだけではうまくファイル一覧を取得できないことが分かった。一度ディレクトリ一覧を作成してから、ファイル一覧を取得する二段階のスクリプトにしてみる。

# ==================================================================================
# 1.ディレクトリ一覧取得
# ==================================================================================
Directories = [p for p in glob('./files/**/',recursive=True)] 
print('===================Directories============================')
for file in Directories:
    print(file)
print('====================================================')
# ==================================================================================
# 2.ファイル一覧取得
# ==================================================================================
files2 = []
for Directory in Directories:
    temp = [p for p in glob(Directory + "**") if os.path.isfile(p)]
    files2.extend(temp)
# 開発時のデバッグ用
print('===================files2============================')
for file2 in files2:
    print(file2)
print('====================================================')

このスクリプトの出力結果は以下のようになる。

出力結果
===================Directories============================
./files\
./files\ParentDirectory\
./files\ParentDirectory\ChildrenDirectory1\
./files\ParentDirectory\ChildrenDirectory2\
====================================================
===================files2============================
./files\ParentDirectory\File1.txt
./files\ParentDirectory\File2.txt
./files\ParentDirectory\File3.txt
./files\ParentDirectory\ChildrenDirectory1\File1.txt
./files\ParentDirectory\ChildrenDirectory1\File2.txt
./files\ParentDirectory\ChildrenDirectory1\File3.txt
./files\ParentDirectory\ChildrenDirectory2\File1.txt
./files\ParentDirectory\ChildrenDirectory2\File2.txt
./files\ParentDirectory\ChildrenDirectory2\File3.txt
====================================================

イメージ通りにファイル一覧を取得できました!

ポイント

  • 「フォルダ一覧を取得」→「ファイル一覧を取得」と二段階にする。
  • 一段階目のglobでファイル指定を「/」で閉じる。例「./files/**/」

次回のブログではこれをもとにhtmlを出力する。

コメント

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