LoginSignup
40
42

More than 3 years have passed since last update.

Pythonでファイルのツリー構造を出力する

Last updated at Posted at 2020-04-17

概要

コマンドのtreeみたいな感じで、Python上でファイルやディレクトリのツリー構造をいい感じに出力する関数を作ったのでメモ。

結論

下記の関数にツリーで表示したいディレクトリのパスを与えれば良い。Mac用に実装しているので、パスがスラッシュで区切られないような場合は非対応。

import pathlib
import glob
import os

def tree(path, layer=0, is_last=False, indent_current=' '):
    if not pathlib.Path(path).is_absolute():
        path = str(pathlib.Path(path).resolve())

    # カレントディレクトリの表示
    current = path.split('/')[::-1][0]
    if layer == 0:
        print('<'+current+'>')
    else:
        branch = '└' if is_last else '├'
        print('{indent}{branch}<{dirname}>'.format(indent=indent_current, branch=branch, dirname=current))

    # 下の階層のパスを取得
    paths = [p for p in glob.glob(path+'/*') if os.path.isdir(p) or os.path.isfile(p)]
    def is_last_path(i):
        return i == len(paths)-1

    # 再帰的に表示
    for i, p in enumerate(paths):

        indent_lower = indent_current
        if layer != 0:
            indent_lower += '  ' if is_last else '│ '

        if os.path.isfile(p):
            branch = '└' if is_last_path(i) else '├'
            print('{indent}{branch}{filename}'.format(indent=indent_lower, branch=branch, filename=p.split('/')[::-1][0]))
        if os.path.isdir(p):
            tree(p, layer=layer+1, is_last=is_last_path(i), indent_current=indent_lower)

例えば、Testというディレクトリが以下のように構成されている場合を考える。

  • Test
    • Test_01
      • bbbbb.txt
      • ccccc.txt
    • Test_02
    • Test_03
    • aaaaa.txt

この時treeを実行するとこんな感じ。

tree('/hogehoge/Test')
出力結果
<Test>
 ├<Test_01>
 │ ├ccccc.txt
 │ └bbbbb.txt
 ├<Test_02>
 ├<Test_03>
 └aaaaa.txt

相対パスで指定しても結果は同じ。

tree('./') # /hogehoge/Test で実行
出力結果
<Test>
 ├<Test_01>
 │ ├ccccc.txt
 │ └bbbbb.txt
 ├<Test_02>
 ├<Test_03>
 └aaaaa.txt
40
42
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
40
42