1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[python] 深さ優先探索でディレクトリ名を再帰的に変更

Last updated at Posted at 2019-03-09

やりたいこと

 あるディレクトリ配下に存在する全てのディレクトリを一括でリネームする. 例えば、このようなディレクトリ構造から


.
├── a.txt
├── dir_1
└── dir_2
    ├── b.txt
    ├── dir_3
    └── dir_4
        ├── c.txt
        ├── dir_5
        └── dir_6

カレントディレクトリ配下のディレクトリを、以下のようなディレクトリ名に再帰的にリネームしたい.

.
├── a.txt
├── new_dir_1
└── new_dir_2
    ├── b.txt
    ├── new_dir_3
    └── new_dir_4
        ├── c.txt
        ├── new_dir_5
        └── new_dir_6

  

How?

深さ優先探索の要領でディレクトリを探索させることで、最も深い階層のディレクトリから優先的にリネームすることができる.


from pathlib2 import Path

def rename_dirs(path):
    path = Path(path)
    dirs = [d for d in path.iterdir() if d.is_dir()]
    for d in dirs:
        rename_dirs(d)
        new_name = "new_" + d.name
        d.rename(d.parent / new_name)    
    
rename_dirs(".")

rename_dirs()は、引数のpath直下にあるサブディレクトリを列挙してから、それぞれのサブディレクトリに対しさらに直下のサブディレクトリを列挙する(再帰処理).これを繰り返し、サブディレクトリをもたないディレクトリまでたどり着いたときに、そのディレクトリのリネームが行われる.また浅い階層(=最下層ではない)ディレクトリのリネームは、自分のサブディレクトリが全てリネームされた段階で逐次実行されることになる.
 

Appendix

 参考までに、pathlibモジュールのglob()を使ってうまくいかなかった例を残しておきます. (glob()の引数**を指定すると、再帰的にディレクトリだけ取得できます.)


from pathlib2 import Path

path = Path(".")
dirs = [d for d in path.glob("**") if not str(d)=="."] #カレントディレクトリをレネーム対象から除いておく 
for d in dirs:
    new_name = "new_" + str(d.name)
    d.rename(d.parent / new_name)
output
FileNotFoundError: [Errno 2] No such file or directory: './dir_2/dir_4' -> './dir_2/new_dir_4'

「そんなファイルないよ」と怒られます.リネームのループ中で、浅い階層にあるディレクトリのリネームを、それより深い階層にあるディレクトリのリネームより前に行ってしまったからです.dir_2new_dir_2と変名されると、次のループで処理対象となるdir_2/dir_4はもう存在しません.(存在するのはnew_dir_2/dir_4)

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?