バッチで同じ拡張子のファイルをマージする


バッチでLhaplusコマンドを使用してファイルを自動解凍する
に引き続き、今度はファイルをマージするバッチになります。

環境

Windows 10
Lhaplus 1.74 (投稿時)
コマンドプロンプト

完成品

@echo off
rem 親フォルダ以下の各フォルダ内で、指定した拡張子のファイルをマージするバッチ
setlocal enabledelayedexpansion

rem ◆変数定義◆
set LOG_FILE=%CD%\log_file.txt
set CURRENT_DIR=%CD%
set S_DATE=%DATE%
set S_TIME=%TIME%
set IS_MERGED_DIR=FALSE

rem ■メイン■
echo "親フォルダ以下の各フォルダ内で、指定した拡張子のファイルをマージします。"
call :guidanceExtention
call :guidanceStart
call :cfmAndDelDir
call :merge
call :dirSearchAndMerge
goto :mergeEnd

rem ◆ガイダンス(拡張子)◆
:guidanceExtention
set /p RES1="マージ対象ファイルの拡張子を入力してください。...[拡張子を入力] "
exit /b

rem ◆ガイダンス(開始)◆
:guidanceStart
set /p RES2="マージを開始しますか?...[Y/N] " 
if /i %RES2%==Y exit /b
if /i %RES2%==YES exit /b
goto :END

rem ◆mergedディレクトリ存在確認◆
:cfmAndDelDir
for /r /d %%1 in (*) do (
    cd %%1
    if /i exist merged (
        echo 削除対象ディレクトリ:%%1\merged
        set IS_MERGED_DIR=True
    )
)
cd %CURRENT_DIR%
if /i %IS_MERGED_DIR%==True call :deleteDir
exit /b

rem ◆一括フォルダ削除◆
:deleteDir
set /p RES3="上記の出力先フォルダが既に存在します。削除してもよろしいですか?...[Y/N] "
if /i %RES3%==Y goto :delOK
if /i %RES3%==YES goto :delOK
goto :END
:delOK
for /r %%2 in (merged) do (
    rmdir /s /q "%%2" > nul 2>&1
)
echo 上記ディレクトリを削除しました。
exit /b

rem ◆実行ディレクトリ配下のディレクトリを調査◆
:dirSearchAndMerge
for /r /d %%3 in (*) do (
    cd %%3
    call :merge %%3
)
exit /b

rem ◆マージ処理◆
:merge
if exist *.%RES1% (
    rem merged.*が無ければ、ディレクトリ作成&マージ処理
    if not exist merged.%RES1% (
        mkdir merged
        echo マージ作業ディレクトリ:%1
        copy /b *.%RES1% merged\merged.%RES1%
    )
)
exit /b

rem ◆終了処理◆
:mergeEnd
echo マージ処理が終了しました。プログラムを終了します。
echo 開始日時:%S_DATE% %S_TIME%
echo 終了日時:%DATE% %TIME%
pause

:end
exit

使い方

※この記事のコードを使用したことにより不都合、不利益が生じても責任は持てませんので使用する際は自己責任でお願いします。
①上記コードをbatで保存。(この時必ず、改行コードはCRLF、文字コードはSJISで保存してください。でないと上手く動作しません。)
②保存したbatファイルをマージしたいファイルがあるディレクトリで実行します。
③画面の質問に応じ、拡張子、開始するしないを入力するとまず出力用のディレクトリが既に存在しないかをチェックし、存在する場合マージを実行する前に削除するかどうかを問います。その後、各ディレクトリに指定した拡張子のファイルが存在する場合、各ディレクトリ毎にマージしファイルをmergedフォルダに出力してくれます。

苦労したところ

  • 一番初めの実行ディレクトリ内の処理を考えるのに時間がかかった。callコマンドで実行する順番を変えて対応した。

おわり

色々ネットを彷徨う中でログも保存しておけたらいいかも!と調べて、typeコマンドを使用する方法を試してみましたがtypeコマンドは実行する毎にファイル内容をすべて読み込むので今回は見送りました。今思えば最後にtypeコマンドを一回だけ実行すればよかったのかも...?
とにかく、できあがってよかったです。