lisz-works

技術と興味の集合体

Python3で対象ファイルを検索→コマンドで一括処理

【スポンサーリンク】

やること

Python3で対象ファイルを検索→アプリへ登録という処理を作ってみました。

対象拡張子のファイルを抽出して、コマンドを作成・実行してアプリへ登録しています。

  1. ファイルを抽出して一括処理したい
  2. コマンドで一括処理したい

なんてときに活用したり、使えるエッセンスがあるんじゃないでしょうか!

やろうとしたこと

対象拡張子のファイルを、あるアプリのコマンドラインで登録する処理。

やること

コレをPythonで作成する。

ファイルは、フォルダ内のサブフォルダに入っている。
それらは流動的で、新しく入ったり消えたりする。

なので、登録済みリストを作り、既に登録されているものは、アプリへの登録処理を行わないようにする。

これでこのPythonを実行するたびに、未登録のものだけど登録していく。

コード全文

長いので畳んであります。

全文を開く

import subprocess
import os.path
import re

# ファイルから一覧を取得
def getfileList(fname):
    f = open(fname)
    list = f.readlines()
    f.close()
    # [line, line, ...]
    return list

# フォルダ内のアイテムリストを作成
def createItemList(fname):
    subprocess.call('dir *.csv /s /b > ' + fname, shell=True)

# 登録済み情報の取得
def readRegisteredInfo(fname):
    registeredInfo = []
    if os.path.exists(fname):
        # 登録済み情報あり
        registeredInfo = getfileList(fname)
    return registeredInfo

# アプリへ登録
def registerApp(fileList, registered, fname):
    app = 'C:\Program Files\XXXX\app.exe'
    f = open(fname, 'a')
    for rawItem in fileList:
        item = re.sub('\n', '', rawItem)    # \n削除
        if not item in registered:
            print('[REGISTER]' + item)
            # アプリに登録
            cmd = '"' + app + '"' + ' add "' + item + '"'
            subprocess.call(cmd)
            # 登録済みリストに追記
            f.write(rawItem)
    f.close()

if __name__ == '__main__':
    listFileName = 'list.txt'
    regFileName = 'registered.txt'
    # DIR内一覧の取得
    createItemList(listFileName)
    fileList = getfileList(listFileName)
    # 登録済情報の取得
    registeredInfo = readRegisteredInfo(regFileName)
    # 登録処理
    registerApp(fileList, registeredInfo, regFileName)
    print('-*-*- DONE -*-*-')

解説

要所要所を解説していきます。

import

importはこれらを行いました。

import subprocess
import os.path
import re

順番に

  1. WindonwsのDOSコマンドを叩くのに使う
  2. ファイルの存在有無を調べるのに使う
  3. 正規表現で置換するのに使う

対象ファイルの一覧を取得する

createItemList()で、list.txtというファイルを実行するたびに作り出しています。

これは

dir *.csv /s /b

というDOSコマンドを実行して、その結果をlist.txtにファイル出力します。

このコマンドは、「対象拡張子のファイルをサブフォルダも含めて検索して、ファイルパスを表示してね」という意味になります。

コレをgetfileList()で、1行1要素として配列にしています。
これで対象ファイルの積んだ配列が完成です。

登録済みチェック用ファイルの読み込み

readRegisteredInfo()で、登録済み情報を取得しています。

os.path.exists(fname)

で対象ファイルが存在するかチェック。

存在する場合、list.txt同様、getfileList()で、1行1要素として配列にして取得します。

アプリへ登録

事前に2つのファイルから取得した配列を使って、アプリへの登録を行います。

ここでやっている「アプリへの登録」は、対象アプリに搭載しているコマンドを実行して行っています。
なので同様に「コンソールからコマンドでなにかする」ということを目的としていれば、同じように「一括で何かを処理!」ということができます。

やっていることは

  1. 対象ファイル配列(fileList)をループで処理
  2. 対象ファイルが登録済み配列に入っていないかチェック
  3. 入っていないなら、コマンドを作成して実行
  4. 登録済み用ファイルを「追記モード」で開いて登録時に要素を追加
item = re.sub('\n', '', rawItem)    # \n削除

はコメントの通り、改行文字をなくしています。

f.readlines()

で読み込むと、改行文字が一緒に入ってしまい、コマンドの実行に支障をきたします。

配列にコレ入ってる?が便利

配列に対して

検索要素 in 配列

とすると、「配列内にこの要素がいるか?」を一撃で調べてくれます。

コレめっちゃ便利。

普通にやると配列をループで検索していかないといけないんですが……

これなら1文で書ける。
しかも構文的にもわかりやすい。

「made in japan」→True/Falseみたいな。

参考

こちらを参考にしました。ありがとうございました!

yukun.info

qiita.com

qiita.com

uxmilk.jp

あとがき

Python3で対象ファイルを検索→コマンドで一括処理についてでした!

とあるアプリで使いたくて作ってみたのですが、わりとサクッと作ることができました。

Pythonは割と簡単に、サクッとやりたいことができるのがいいですね。

今回使った「DOSコマンドの実行」があれば、「バッチファイルの代わりにPythonでもう少し複雑な処理を……!」なんてこともできそうですね。

なにか作るときに視野に入れて見てみるといいんじゃないでしょうか!?