KENTOLAB

vuePress-theme-reco KEN    2019 - 2023
KENTOLAB KENTOLAB

Choose mode

  • dark
  • auto
  • light
Home
Category
  • LIFE
  • TECH
Tag
About
  • me
TimeLine
Contact
  • instagram
  • twitter
  • contact form
author-avatar

KEN

31

Article

30

Tag

Home
Category
  • LIFE
  • TECH
Tag
About
  • me
TimeLine
Contact
  • instagram
  • twitter
  • contact form

Pythonでファイルに連番をつけてコピーする

vuePress-theme-reco KEN    2019 - 2023

Pythonでファイルに連番をつけてコピーする

KEN 2020-05-23 Python

# 概要

なんとかして作業効率向上を図りたいシリーズ。

写真が多い投稿などで、撮影した写真から抜粋して投稿する際、カメラによって命名されたファイル名だと統一感がない。

また、番号が連番ではなくなってしまい気持ちわるいので、連番でファイルをリネームしてコピーすることにした。

# 作りたいものとか

とりあえず以下のようなものを作りたい。

  • 任意のディレクトリ内の任意の拡張子ファイルにprefixと通し番号を付け、別ディレクトリにコピー
  • 連番は${prefix}_001, ${prefix}_002...とする
    • ファイルのまとまりは1記事専用にするので、100枚限度として_00でもいいかも
  • ファイル名のprefixは引数で指定
  • 走査対象拡張子も引数で指定
  • prefixはディレクトリ名にも使用する
  • 自分さえ使えればいいという大前提

# できあがったもの

こんな感じ。

### HOW TO USE (1)
# python ./file_rename_copier.py [directory path includes imgs] [new directory/file name] [file extension]
#
# e.g.
# python ./file_rename_copier.py ./img/test_imgs/ test JPG
# -> create [test] directory and [test_000, test_001...] files from ./img/test_imgs/*.JPG.

import argparse
import sys
import os
import shutil
import glob

def rename_copy(img_dir, ctg_name, file_ext):
    imgs = glob.glob(img_dir+'*.'+file_ext)
    imgs.sort()

    if not os.path.exists(os.path.join('./copied_img', ctg_name)):
        os.makedirs(os.path.join('./copied_img', ctg_name))

    copied_file_cnt = 0
    # copy files
    print('{:-^100}'.format(' copy start! '))
    for i, img in enumerate(imgs):

        # create new file path
        ext = os.path.splitext(img)
        new_file_path = os.path.join('./copied_img/', ctg_name, ctg_name+'_'+str(i)+ext[1])

        # copy file
        shutil.copy(img, new_file_path)
        print('copied : {} ----->> {}'.format(img, new_file_path))
        copied_file_cnt += 1

    print('{:>4} files has been copied.'.format(copied_file_cnt))
    print('{:-^100}'.format(' complete! '))

def main(args):
    img_dir = args.img_dir
    ctg_name = args.ctg_name
    file_ext = args.file_ext

    rename_copy(img_dir, ctg_name, file_ext)

if __name__ == '__main__':
    parser = argparse.ArgumentParser()

    parser.add_argument(
        'img_dir',
        help='Specify target image directory.',
        type=str)
    parser.add_argument(
        'ctg_name',
        help='Category name will be used for file name.',
        type=str)
    parser.add_argument(
        'file_ext',
        help='Specify target file extension.',
        type=str)
    args = parser.parse_args()
    main(args)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

(1)いつも使い方を忘れるのでコマンドと実行結果をメモ
(2)コピーしたリネーム済みファイルを格納するディレクトリを作成
(3)リネームしながらコピー処理、標準出力

# 結果

実行後出力はこんな感じ。

Kento$ python file_rename_copier.py ./original/test/ test JPG
------------------------------------------- copy start! --------------------------------------------
copied : ./original/test/IMG_6013.JPG ----->> ./copied_img/test/test_000.JPG
copied : ./original/test/IMG_6021.JPG ----->> ./copied_img/test/test_001.JPG
copied : ./original/test/IMG_6023.JPG ----->> ./copied_img/test/test_002.JPG
copied : ./original/test/IMG_6033.JPG ----->> ./copied_img/test/test_003.JPG
copied : ./original/test/IMG_6038.JPG ----->> ./copied_img/test/test_004.JPG
copied : ./original/test/IMG_6044.JPG ----->> ./copied_img/test/test_005.JPG
copied : ./original/test/IMG_6049.JPG ----->> ./copied_img/test/test_006.JPG
   7 files has been copied.
-------------------------------------------- complete! ---------------------------------------------
1
2
3
4
5
6
7
8
9
10
11

オリジナル画像について、そこそこ遠いパスを想定しているので、標準出力を綺麗に整形できるように横幅は100文字分取っています。

# 迷って消したもの

本当はファイルが重複していたらスキップ、というものを考えていたけど、iカウンターでナンバリングしてしまっているので、例えばオリジナル画像を追加した時に、その通し番号によっては意味がない(全部番号がずれる)ので消した。[1]

	# file exist check
    if os.path.exists(new_file_path):
        print('WARNING: {} already exists!'.format(new_file_path))
        continue
1
2
3
4

上書き防止の意味では有効だったかも。

ただし、前述の通りこのスクリプトは1記事用の連番ファイルを都度作成する、という意図があったので、既存のディレクトリを指定することを想定していない。

↑というはじきかたを最初に入れとけばよかったのかも。[2]

# つまずいたところ

# format

調べればなんてことなかったけど、開始と終了の標準出力を揃えようとして、-で線を引くのに予想外に時間をかけた気がする。

というかあまり{}だらけでformatすると可読性が悪いような。

# メモ

  • 相変わらず英文は適当
  • エラー処理は皆無。ファイルがあること、コピー先にファイルがないことが大前提
  • 容赦無く上書き。オリジナルは別個で確実に存在している前提なので
  • 最初にディレクトリのexistチェックだけ入れたらいいのかも

  1. この一文は説明端折りすぎですね。笑 ↩︎

  2. 弾きかた、と書くと別の読み方をしたくなるので。 ↩︎