【Python】 Python ~ 基本編 / フォルダ・ファイル操作 ~

■ はじめに

Python での以下のようなことを扱える方法を調べてみた

【1】フォルダ/ファイルの存在有無
【2】フォルダ/ファイルかどうか判定
【3】フォルダの作成
【4】フォルダ/ファイルのコピー
【5】フォルダ/ファイルの削除
【6】フォルダ/ファイルの移動、リネーム
【7】フォルダ配下のフォルダ/ファイル一覧
【8】パスの結合
【9】パスの分割(拡張子の取得・判定含む)
 1)分割(パス、ファイル名、拡張子)
 2)ファイル名 or フォルダ名 のみ抽出
 3)パスのみ抽出
 4)直近の親フォルダ名を取得する
etc...

【1】 フォルダ/ファイルの存在有無

サンプル

例1:フォルダの有無

import os

def main():
    if os.path.exists('C:\\folderA'):
        print('ある')
    else:
        print('ない')

    if os.path.exists('C:\\folderA\\hello.txt'):
        print('ある')
    else:
        print('ない')

if __name__ == '__main__':
    main()

【2】フォルダ/ファイルかどうか判定

フォルダかどうか

os.path.isdir() を使う

ファイルかどうか

os.path.isfile() を使う

例1:フォルダ/ファイルかどうか判定

import os

def main():
    input_path = 'C:\\work\\hello'
    if os.path.isdir(input_path):
        print("フォルダです")
    else:
        print("フォルダではない")

    input_file_path = 'C:\\work\\hello\\hello.txt'
    if os.path.isfile(input_file_path):
        print("ファイルです")
    else:
        print("ファイルではない")

if __name__ == '__main__':
    main()

【3】フォルダの作成

makedirs(path[, exist_ok=True]) を使用する
 => 『exist_ok=True』はフォルダがあっても例外を発生しない

サンプル

例1:フォルダがなかったらフォルダ作成

import os

def main():
    path = 'C:\\work\\aaa\\bbb'
    if not os.path.exists(path):
        os.makedirs(path)
    # 補足:「exist_ok」ってのある
    # os.makedirs(path, exist_ok=True)

if __name__ == '__main__':
    main()

【4】フォルダ/ファイルのコピー

ディレクトリごとのコピー
 ... shutil.copytree(src, dst)

サンプル

from distutils.dir_util import copy_tree
import shutil

def main():
    input_path = 'C:\\work\\hello'
    input_path2 = 'C:\\work\\hello_clone'
    copy_tree(input_path, input_path2)

    input_file_path = 'C:\\work\\hello\\hello.txt'
    input_file_path2 = 'C:\\work\\hello\\hello_clone.txt'
    shutil.copyfile(input_file_path, input_file_path2)

if __name__ == '__main__':
    main()

【5】フォルダ/ファイルの削除

* フォルダ削除
 shutil.rmtree(path)
  => 引数は、ディレクトリを示すパスのみ
  => ファイルだとエラー

* ファイル削除
 os.remove(file_path)

サンプル

例1:フォルダがあったらフォルダ削除

import os
import shutil

def main():
    path = 'C:\\work\\aaa'
    if os.path.exists(path):
        shutil.rmtree(path)

if __name__ == '__main__':
    main()

例2:ファイルがあったらファイル削除

import os

def main():
    file_path = 'C:\\work\\hello.txt'
    if os.path.exists(file_path):
        os.remove(file_path)

if __name__ == '__main__':
    main()

【6】フォルダ/ファイルの移動、リネーム

* フォルダ/ファイルの移動
 shutil.move(src, dst)

* フォルダ/ファイルのリネーム
os.rename(src, dst)

【7】 フォルダ配下のフォルダ/ファイル一覧

 1) os.listdir(path)
 2) os.walk(path)
 3) glob.glob(path)

サンプル

例1:listdirを利用する

import os

def main():
    directoryList = os.listdir('C:\\folderA')
    print(directoryList)

if __name__ == '__main__':
    main()

出力結果例

['.idea', 'git', 'hello.txt', 'folder2']

例2:walkを利用する

import os

def main():
  print('===================')

  for current_dir, dirs, files in os.walk(
    r"C:\folderA",
    topdown=False):
    print("現在のディレクトリ: " + current_dir)
    for dir in dirs:
      print("内包するディレクトリ:" + dir)
      for file in files:
        print("内包するファイル: " + file)

if __name__ == '__main__':
    main()

例3:globを利用する

import glob

for full_path in glob.glob(r"C:\tmp\aaa\*\*.csv"):
  print("現在のディレクトリ: " + full_path)

  path = os.path.dirname(full_path)
  print(" path = " + path)
  parent_dir_name = os.path.basename(path)
  print(" parent_dir_name = " + parent_dir_name)
"""
C:\tmp\aaa
 + bbb1
  + ccc1_1
    + ccc1
      + ccc1_1.csv
   + bbb1_1.csv << Target
   + bbb1_2.csv << Target
 + bbb2
    + ccc2
      + ccc2_1.csv
   + bbb2_1.csv << Target
   + bbb2_2.txt
 + bbb3
    + ccc3
      + ccc3_1.csv
   + bbb2_1.txt
 + aaa1.csv
"""
# 現在のディレクトリ: C:\tmp\aaa\bbb1\bbb1_1.csv
#  path = C:\tmp\aaa\bbb1
#  parent_dir_name = bbb1
# 現在のディレクトリ: C:\tmp\aaa\bbb1\bbb1_2.csv
#  path = C:\tmp\aaa\bbb1
#  parent_dir_name = bbb1
# 現在のディレクトリ: C:\tmp\aaa\bbb2\bbb2_1.csv
#  path = C:\tmp\aaa\bbb2
#  parent_dir_name = bbb2

【8】パスの結合

os.path.join(path1, path2, ...)

【9】パスの分割(拡張子の取得・判定含む)

1)分割(パス、ファイル名、拡張子)

import os

file_name = 'input.csv'
# ('', 'input.csv')
print(os.path.split(file_name))
# ('input', '.csv')
print(os.path.splitext(file_name))

path = 'C:/tmp/input.csv'
# ('C:/tmp', 'input.csv')
print(os.path.split(path))
# ('C:/tmp/input', '.csv')
print(os.path.splitext(path))

s3_path = 's3://your-bucket/xxx/sample.txt'
# ('s3://your-bucket/xxx', 'sample.txt') 
print(os.path.split(s3_path))
# ('s3://your-bucket/xxx/sample', '.txt')
print(os.path.splitext(s3_path))

path, file_extention = os.path.splitext(s3_path)
# True
print(file_extention in ['.txt', '.csv'])
# False
print(file_extention in ['.sql', '.hql'])
# False
print(file_extention not in ['.txt', '.csv'])
# True
print(file_extention not in ['.sql', '.hql'])

2)ファイル名 or フォルダ名 のみ抽出

# input.csv
print(os.path.basename(path))

3)パスのみ抽出

# C:/tmp
print(os.path.dirname(path))

4)直近の親フォルダ名を取得する

# tmp
print(os.path.basename(os.path.dirname(path)))

https://note.nkmk.me/python-os-basename-dirname-split-splitext/

サンプル

import os

# ファイル名(拡張子なし)
def get_filename_without_ext(target_path):
  file_name = os.path.basename(target_path)
  return os.path.splitext(file_name)[0]

# 親フォルダ名
def get_parent_dir_name(target_path):
  return os.path.basename(os.path.dirname(target_path))

# ('/abc/def', 'hello.txt')
print(os.path.split('/abc/def/hello.txt'))

# ('/abc/def/hello', '.txt')
print(os.path.splitext('/abc/def/hello.txt'))

# hello.txt
print(os.path.basename('/abc/def/hello.txt'))

# hello
print(get_filename_without_ext('/abc/def/hello.txt'))

# /abc/def
print(os.path.dirname('/abc/def/hello.txt'))

# def
print(get_parent_dir_name('/abc/def/hello.txt'))

参考文献

https://qiita.com/supersaiakujin/items/12451cd2b8315fe7d054
https://akamist.com/blog/archives/3013
https://qiita.com/amowwee/items/e63b3610ea750f7dba1b
https://qiita.com/Morio/items/f34dab8825c9d76664f5
https://www.sejuku.net/blog/63816

関連記事

Python 基本編

文字列
https://dk521123.hatenablog.com/entry/2019/10/12/075251