私は bash などのシェルでのディレクトリ操作、ファイル操作の頻用コマンドは頭に入っているのですが、Pythonで同じことをやろうとするといつも戸惑います。なので、一覧表を作成してみました。なお、近年は os モジュールよりも pathlib モジュールがよく使われるとのことでその対応表もまとめてみました。なお、 os モジュールの説明中に shutil も入っています。コピーや削除はこちらを使うので、ここに入れておきます。
基本的なディレクトリ操作
| 操作 | bash | os | pathlib (Path) |
|---|---|---|---|
| カレントディレクトリの取得 | pwd | os.getcwd() | Path.cwd() |
| ディレクトリ内容の表示 | ls | os.listdir(‘.’) | [ p.name for p in Path(‘.’).iterdir() ] |
| ディレクトリ移動 | cd path | os.chdir(‘path’) | 該当なし |
| ディレクトリ作成 | mkdir dir | os.mkdir(‘dir’) | Path(‘dir’).mkdir() |
| 親含めて作成 | mkdir -p dir/sub | os.makedirs(‘dir/sub’, exist_ok=True) | Path(‘dir/sub’).mkdir(parents=True, exist_ok=True) |
ファイル/ディレクトリの確認
| 操作 | bash | os | pathlib (Path) |
|---|---|---|---|
| 存在確認 | [ -e path ] | os.path.exists(‘path’) | Path(‘path’).exists() |
| ファイル確認 | [ -f path ] | os.path.isfile(‘path’) | Path(‘path’).is_file() |
| ディレクトリ確認 | [ -d path ] | os.path.isdir(‘path’) | Path(‘path’).is_dir() |
| シンボリックリンク確認 | [ -L path ] | os.path.islink(‘path’) | Path(‘path’).is_symlink() |
ファイル/ディレクトリの削除
| 操作 | bash | os | pathlib (Path) |
|---|---|---|---|
| ファイル削除 | rm file | os.remove(‘file’) | Path(‘file’).unlink() |
| 空ディレクトリ削除 | rmdir dir | os.rmdir(‘dir’) | Path(‘dir’).rmdir() |
| ディレクトリごと削除 | rm -r dir | shutil.rmtree(‘dir’) | 該当なし |
ファイル/ディレクトリの移動・コピー
| 操作 | bash | os | pathlib (Path) |
|---|---|---|---|
| 名前変更/移動 | mv old new | os.rename(‘old’, ‘new’) | Path(‘old’).rename(‘new’) |
| コピー | cp file dst | shutil.copy(‘file’, ‘dst’) | 該当なし |
| ディレクトリコピー | cp -r dir dst | shutil.copytree(‘dir’, ‘dst’) | 該当なし |
パス操作
| 操作 | bash | os | pathlib (Path) |
|---|---|---|---|
| パス結合 | $dir/$file | os.path.join(dir, file) | Path(dir) / file |
| 絶対パス取得 | realpath file | os.path.abspath(‘file’) | Path(‘file’).resolve() |
| ディレクトリ名取得 | dirname /a/b/c | os.path.dirname(‘/a/b/c’) | Path(‘/a/b/c’).parent |
| ファイル名取得 | basename /a/b/c.txt | os.path.basename(‘/a/b/c.txt’) | Path(‘/a/b/c.txt’).name |
| 拡張子なし名前 | basename file .txt | os.path.splitext(‘file.txt’)[0] | Path(‘file.txt’).stem |
| 拡張子取得 | ${file##*.} | os.path.splitext(‘file.txt’)[1] | Path(‘file.txt’).suffix |
各コマンドの詳細説明
以下にPythonで実際に osモジュールと pathlib の Pathモジュールをどのように使用するか例を記載しておきます。
0. デモの準備
ここはシェルスクリプトで準備します。ホームディレクトリの下に comp_os_pathlib というディレクトリを作成し、その下に file0.txt, file1.txt, file2.txt と dir0 と dir1 を準備します。
cd $HOME
mkdir comp_os_pathlib
cd comp_os_pathlib
touch file{0..2}.txt
mkdir dir{0..1}
python3
1. カレントディレクトリを取得 (pwd)
- osモジュール
import os current_dir = os.getcwd() print(current_dir) # '/home/user/comp_os_pathlib'
- pathlibモジュール
from pathlib import Path current_dir = Path.cwd() print(current_dir) # '/home/user/comp_os_pathlib'
2. ディレクトリ内容の一覧表示 (ls)
- osモジュール
import os
files = os.listdir('.')
print(files) # ['dir1', 'dir0', 'file0.txt', 'file2.txt', 'file1.txt']
- pathlibモジュール
from pathlib import Path
files = [ p.name for p in Path('.').iterdir() ]
print(files) #['dir1', 'dir0', 'file0.txt', 'file2.txt', 'file1.txt']
# pathlib は、ファイルやディレクトリの属性も持っているため
# ファイル一覧だけ、ディレクトリ一覧だけ出せる
file_only = [ p.name for p in Path('.').iterdir() if p.is_file() ]
print(file_only) # ['file0.txt', 'file2.txt', 'file1.txt']
dir_only = [ p.name for p in Path('.').iterdir() if p.is_dir() ]
print(dir_only) # ['dir1', 'dir0']
3. ディレクトリ移動
- osモジュール
import os
os.chdir('/path/to/directory')
- pathlibモジュール
- 該当なし
4. ディレクトリ作成
- osモジュール
import os
# 単一ディレクトリ作成
os.mkdir('dir2')
# 親ディレクトリも含めて作成
os.makedirs('dir3/dir3-0/dir3-0-0', exist_ok=True)
- pathlibモジュール
from pathlib import Path
# 単一ディレクトリ作成
Path('dir2').mkdir()
# 親ディレクトリも含めて作成
Path('dir3/dir3-0/dir3-0-0').mkdir(parents=True, exist_ok=True)
5. ファイル削除とディレクトリ削除
- osモジュールおよびshutilモジュール
import os
import shutil
# ファイル削除
os.remove('file.txt')
# 空のディレクトリ削除
os.rmdir('empty_dir')
# 中身があるディレクトリごと削除
shutil.rmtree('dir_with_contents')
- pathlibモジュール
from pathlib import Path
# ファイル削除
Path('file.txt').unlink()
# 空のディレクトリ削除
Path('empty_dir').rmdir()
# 中身があるディレクトリごと削除
# pathlibには該当なし - shutilを使用
6. ファイル・ディレクトリのコピー
osモジュール、pathlibモジュールではできないので、shutilモジュールを使用する
import shutil
# ファイルコピー
shutil.copy('source.txt', 'destination.txt')
# ディレクトリコピー
shutil.copytree('source_dir', 'dest_dir')
7. パス操作
- osモジュール
import os
# パス結合
path = os.path.join('data', 'raw', 'input.csv')
# ファイル名、拡張子の取得
file_path = 'data/raw/input.csv'
print(os.path.basename(file_path)) # 'input.csv'
print(os.path.splitext(file_path)[0]) # 'data/raw/input'
print(os.path.splitext(file_path)[1]) # '.csv'
- pathlibモジュール
from pathlib import Path
# パス結合
# pathlib(/演算子で直感的)
path = Path('data') / 'raw' / 'input.csv'
# ファイル名、拡張子の取得
file_path = 'data/raw/input.csv'
p = Path(file_path)
print(p.name) # 'input.csv'
print(p.stem) # 'input'
print(p.suffix) # '.csv'
ありがとうございます!こういうのが欲しかったです。
ちなみに、コマンドボックスの中にhtmlタグが残っている気がするのですが、自分の環境だけでしょうか・・・?
ご指摘ありがとうございます!修正します。