スクリプト作成_ファイル振り分け


はじめに

アプリの処理で作成されたファイルを条件に基づいて移動、コピーするスクリプトの作成を依頼された。
前回、前々回とスクリプトの作成スキルがあることを理解してもらえたようで、すぐに自分に依頼が来た。
聞いた限り複雑な条件や仕組みでは無さそうなのですぐ終わりそうです。

仕様

①アプリの仕様で下記のようにいくつか命名規則を持ったファイルが作成される
先頭が「A_」で始まるファイル 例:A_TEST
先頭が「B_」で始まるファイル 例:B_TEST
先頭が「AB_」で始まるファイル 例:AB_TEST
それ以外 例:C_TEST

②これらのファイルを仕分けし、以下のような処理を行う
A_の場合
・「読み込み用フォルダ」に移動
B_の場合
・「その他のフォルダ」に移動
AB_の場合
・「読み込み用フォルダ」にファイルをコピーした後、元ファイルを「その他のフォルダ」に移動
それ以外の場合
・「エラー用フォルダ」に移動したあと、指定の返り値(ここでは255)を返す
※例外処理はJP1側で実装するため。今回は返り値の指定のみ

③以下のような階層構成になる
/work (作業領域:スクリプト本体やログ、一時ファイルの出力先)
└/test (実際のファイルやフォルダが配置されている)
 ̠├/ReadOnly (読み込み用フォルダ)
 ├/Other (その他のフォルダ)
 └/Error (エラー用フォルダ)

◆コマンドのピックアップ◆
前回作成した「スクリプト作成_ファイル・フォルダ情報の確認」から流用する。
一部追加したもののみピックアップします。

findstr
findstr /I /B "A_"
rem /I      :小文字大文字を区別しない
rem /B "A_" :先頭文字列が"A_"のファイルを検索
copy
copy DIRPATH1\FILE1 DIRPATH2\FILE1 
rem FILE1  DIRPATH2 配下にコピーする(robocopyでは単体コピーができないため使用)
move
move DIRPATH1\FILE1 DIRPATH2\ 
rem FILE1  DIRPATH2 配下に移動する

実際に作ってみた

file_sorting.bat

@echo off
setlocal EnableDelayedExpansion

rem *-------------------------------*
rem 
rem     ファイル振り分けbat
rem 
rem *-------------------------------*
rem 
rem YYYY.MM.DD  :新規作成

rem 日付表記がYYYYMMDD
set TODAY=%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%
set LOG=H:\work\test\FileSorting_%TODAY%.txt

rem 作業ディレクトリ
set WORKPATH=H:\work\test
set FILELIST=H:\work\LIMS_File.csv
set cnt=0
set err_cnt=0

rem 対象ファイルのピックアップ
dir /b /a-d %WORKPATH% > %FILELIST%

rem 処理開始時間
echo ########## >> %LOG% 2>&1
echo START %TIME% >> %LOG% 2>&1
echo ########## >> %LOG% 2>&1

rem ファイルの振り分け
for /f %%a in ( %FILELIST% ) do (
    set FILENAME=%%a
    set cnt=0

    rem 先頭文字列[AB]
    echo !FILENAME! | findstr /I /B "AB_" > nul
    if not ERRORLEVEL 1 (
        echo !FILENAME! >> %LOG% 2>&1
        copy %WORKPATH%\!FILENAME! %WORKPATH%\ReadOnly\!FILENAME! >> %LOG% 2>&1
        move %WORKPATH%\!FILENAME! %WORKPATH%\Other\ >> %LOG% 2>&1
        set cnt=1
    )

    rem 先頭文字列[B]
    if !cnt!==0 (
        echo !FILENAME! | findstr /I /B "B_" > nul
        if not ERRORLEVEL 1 (
            echo !FILENAME! >> %LOG% 2>&1
            move %WORKPATH%\!FILENAME! %WORKPATH%\Other\ >> %LOG% 2>&1
            set cnt=1
        )
    )

    rem 先頭文字列[A]
    if !cnt!==0 (
        echo !FILENAME! | findstr /I /B "A_" > nul
        if not ERRORLEVEL 1 (
            echo !FILENAME! >> %LOG% 2>&1
            move %WORKPATH%\!FILENAME! %WORKPATH%\ReadOnly\ >> %LOG% 2>&1
            set cnt=1
        )
    )

    rem その他
    if !cnt!==0 (
        echo !FILENAME! is Exception File >> %LOG% 2>&1
        move %WORKPATH%\!FILENAME! %WORKPATH%\Error\ >> %LOG% 2>&1
        set err_cnt=1
    )
)

rem 処理完了時間
echo ########## >> %LOG% 2>&1
echo END %TIME% >> %LOG% 2>&1
echo ########## >> %LOG% 2>&1

del %FILELIST%

rem 例外ファイルが存在した場合
if %err_cnt%==1 (
    goto :Err_call
)

exit /b 0
endlocal

:Err_call
exit /b 255
endlocal

おわりに

想定したファイルの振り分け、例外ファイルが存在した場合のエラー検知を実現することができた。
今回のスクリプトでは、①ファイル名の識別方法、②条件ごとにアクション、③エラー判定を外部に連携、と比較的わかりすいし、簡単に実装できるものだったのでそこまで時間はかからなかった。