【バッチスクリプト】処理件数をカウントし表示する処理を追加

いつもお世話になっております。
RfromLです。

今回はバッチスクリプトでなんらかの処理を行った時に処理件数をカウントして表示する機能の追加についてです。


1.はじめに

今回は以前「【Windows】バッチスクリプトでヘッダーレコード(先頭行)を除外」で作成したバッチスクリプトに対し処理件数を表示するように修正します。
処理の修正を通して、処理件数カウントの処理について解説します。



2.処理(修正)概要

今回修正を行うバッチスクリプト内で、修正対象となる箇所の「ヘッダー除外・ファイル結合処理」処理の内容は以下となっています。

[修正前:処理内容]
①入力ファイルディレクトリに格納されたファイルの一覧をdir /b コマンドで出力する。
②「①」で出力したファイル一覧からfor文で1件づつ次のfor文にファイル名を渡して存在したファイルの数だけ以下 「a. ~ b.」 の処理を繰り返す。
 a.「②」で渡されたファイル名のファイルを読み込む。
 b.読み込んだファイルに対し、ファイルの最後まで以下の処理を繰り返す。
  ・ファイルの1レコード目の場合は、読込をスキップする。
  ・ファイル内容をechoでファイルに出力する。


上記の[修正前:処理内容]に今回の対応で処理件数を表示するように修正した処理の内容が以下となります。


[修正後:処理内容]
①入力ファイルディレクトリに格納されたファイルの一覧をdir /b コマンドで出力する。
②「①」で出力したファイル一覧からfor文で1件づつ次のfor文にファイル名を渡して存在したファイルの数だけ以下 「a. ~ c.」 の処理を繰り返す。
 a.「②」で渡されたファイル名のファイルを読み込む。
 b.読み込んだファイルに対し、ファイルの最後まで以下の処理を繰り返す。
  ・ファイルの1レコード目の場合は、読込をスキップする。
  ・入力レコード件数をカウントアップ(1加算)する。
  ・ファイル内容をechoでファイルに出力する。
  ・出力レコード件数をカウントアップ(1加算)する。
 c.入力レコード件数をechoで表示する。
③出力レコード件数をechoで表示する。

赤字の箇所が修正後に追記した内容です。




3.作成スクリプト

3-1.コード内容

今回修正したスクリプトファイルのコード内容は以下の通りです。

[ HeaderExclusion.bat ]

@echo off
@rem ------------------------------------------------------------
@rem システム名         : RfromL.com
@rem 処理ID             : HeaderExclusion
@rem 処理名             : ヘッダーレコード除外処理
@rem 処理内容           : ①ヘッダーレコード除外
@rem                    : ②入力ファイル結合
@rem                    : ③結合ファイルを昇順でソート
@rem 作成日             : 2022.07.25
@rem 作成者             : S.Takaaze
@rem パラメータ         : なし
@rem 備考               : 
@rem 
@rem *** 修正履歴 ***********************************************
@rem No.  日付        修正者              内容
@rem 001  2022.07.25  S.Takaaze  新規作成
@rem 002  2025.03.15  S.Takaaze  処理件数表示追加対応
@rem ------------------------------------------------------------
@rem - 初期処理
@rem ------------------------------------------------------------
:STEP000

@rem 実行バッチファイルディレクトリ設定
set CMD_PATH=%~dp0

@rem 処理ID設定(バッチファイル名)
set BATCH_ID=%~n0

@rem add-sta 002  2025.03.15  S.Takaaze  処理件数表示追加対応
@rem 処理開始メッセージ表示
echo %BATCH_ID% 処理開始
@rem add-end 002  2025.03.15  S.Takaaze  処理件数表示追加対応


@rem ------------------------------------------------------------
@rem - 日時情報取得処理
@rem ------------------------------------------------------------
:STEP010

@rem システム日付取得(YYYY=年,MM=月,DD=日,WK=曜日)
set YYYY=%date:~0,4%
set MM=%date:~5,2%
set DD=%date:~8,2%
set WK=%date:~0,1%

@rem システム時刻取得(HH=時)
@rem ※HH部分(時間部分)の1文字目をチェックして
@rem   空白の場合は頭ゼロ埋めでセット
set HHCHK=%time:~0,1%

if "%HHCHK%"==" " (
  set HH=0%time:~1,1%
) else (
  set HH=%time:~0,2%
)

@rem システム時刻取得(MI=分,SS=秒)
set MI=%time:~3,2%
set SS=%time:~6,2%

set DATETIME=%YYYY%%MM%%DD%_%HH%%MI%%SS%



@rem ------------------------------------------------------------
@rem - ファイルディレクトリ設定
@rem ------------------------------------------------------------
:STEP020

@rem 入力ファイルディレクトリ
set IDIR=%CMD_PATH%\IN

@rem 中間ファイルディレクトリ
set TDIR=%CMD_PATH%\TRN

@rem 出力ファイルディレクトリ
set ODIR=%CMD_PATH%\OUT



@rem ------------------------------------------------------------
@rem - ファイルID設定
@rem ------------------------------------------------------------
:STEP030

@rem 中間ファイルID
set TFILEID001=prices_trn.txt

@rem 出力ファイルID
set OFILEID001=prices_out.txt

@rem 前回出力ファイルバックアップID
set BFILEID001=prices_out_%DATETIME%.txt



@rem ------------------------------------------------------------
@rem - ファイル設定
@rem ------------------------------------------------------------
:STEP040

@rem 中間ファイル
set TFILE001=%TDIR%\%TFILEID001%

@rem 出力ファイル
set OFILE001=%ODIR%\%OFILEID001%



@rem ------------------------------------------------------------
@rem - 前処理 : 中間ファイルクリア処理
@rem ------------------------------------------------------------
:STEP050

if exist "%TFILE001%" del "%TFILE001%"



@rem ------------------------------------------------------------
@rem - 前処理 : 前回出力ファイルバックアップ処理
@rem ------------------------------------------------------------
:STEP060

if exist "%OFILE001%" ren "%OFILE001%" "%BFILEID001%"



@rem ------------------------------------------------------------
@rem - ヘッダー除外・ファイル結合処理
@rem ------------------------------------------------------------
:STEP070

@rem change-del-sta 002  2025.03.15  S.Takaaze  処理件数表示追加対応
@rem for /F %%i in ('dir /b %IDIR%') do (
@rem   for /F "skip=1 tokens=* usebackq" %%j in ("%IDIR%\%%i") do @echo %%j>> "%TFILE001%"
@rem )
@rem change-del-end 002  2025.03.15  S.Takaaze  処理件数表示追加対応
@rem change-add-sta 002  2025.03.15  S.Takaaze  処理件数表示追加対応

@rem 出力レコードカウンター初期化
set OCNT=0

@rem 遅延環境変数有効
setlocal enabledelayedexpansion

@rem 入力ファイル一覧取得
for /F %%i in ('dir /B %IDIR%') do (

  @rem 入力レコードカウンター初期化
  set ICNT=0

  @rem 入力ファイル読込(ファイル毎の1レコード目はskip=1指定で読み飛ばし)
  for /F "skip=1 tokens=* usebackq" %%j in ("%IDIR%\%%i") do (

    @rem 入力レコード件数カウントアップ
    set /A ICNT=!ICNT!+1

    @rem データレコード出力
    @echo %%j>> "%TFILE001%"

    @rem 出力レコード件数カウントアップ
    set /A OCNT=!OCNT!+1

  )

  @rem 入力レコード件数表示
  @echo   I-FILE [ %%i ] !ICNT!件 ※ヘッダーレコード除く
)

@rem 出力レコード件数表示
@echo   O-FILE [ %TFILEID001% ] %OCNT%件

@rem 遅延環境変数無効
endlocal
@rem change-add-end 002  2025.03.15  S.Takaaze  処理件数表示追加対応



@rem ------------------------------------------------------------
@rem - ソート処理(昇順)
@rem ------------------------------------------------------------
:STEP080

sort "%TFILE001%" /O "%OFILE001%"



@rem ------------------------------------------------------------
@rem - 正常終了処理
@rem ------------------------------------------------------------
:END

@rem add-sta 002  2025.03.15  S.Takaaze  処理件数表示追加対応
@rem 処理終了メッセージ表示
echo %BATCH_ID% 処理終了

@rem 表示メッセージ確認の為、処理一時停止
pause

@rem add-end 002  2025.03.15  S.Takaaze  処理件数表示追加対応

exit 0

3-2.修正前後比較

修正前のソースと修正後のソースをファイル比較ソフト「Diff」を使って比較します。

ここで確認するポイントは以下の2点です。
 ①余計な箇所が変更されていないこと
 ②修正の必要な箇所が正しく修正されていること

[ DIFF比較結果 ]


この記事内では先頭部分の差分のみ画像を提示していますが、実際は差分箇所を全部確認します。


3-3.修正箇所説明

今回の対応で修正した箇所を、ソースの先頭から説明します。


[修正箇所1]

@rem add-sta 002 2025.03.15 S.Takaaze 処理件数表示追加対応 @rem 処理開始メッセージ表示 echo %BATCH_ID% 処理開始 @rem add-end 002 2025.03.15 S.Takaaze 処理件数表示追加対応

処理件数を表示するにあたってメッセージを見やすくする為、処理開始メッセージの表示を追加します。



[修正箇所2]

@rem change-del-sta 002  2025.03.15  S.Takaaze  処理件数表示追加対応
@rem for /F %%i in ('dir /b %IDIR%') do (
@rem   for /F "skip=1 tokens=* usebackq" %%j in ("%IDIR%\%%i") do @echo %%j>> "%TFILE001%"
@rem )
@rem change-del-end 002  2025.03.15  S.Takaaze  処理件数表示追加対応

記述方式が大幅に変わるので、for文箇所をまるごとコメントアウトします。


[修正箇所3]

@rem change-add-sta 002  2025.03.15  S.Takaaze  処理件数表示追加対応

@rem 出力レコードカウンター初期化
set OCNT=0

@rem 遅延環境変数有効
setlocal enabledelayedexpansion

@rem 入力ファイル一覧取得
for /F %%i in ('dir /B %IDIR%') do (

  @rem 入力レコードカウンター初期化
  set ICNT=0

  @rem 入力ファイル読込(ファイル毎の1レコード目はskip=1指定で読み飛ばし)
  for /F "skip=1 tokens=* usebackq" %%j in ("%IDIR%\%%i") do (

    @rem 入力レコード件数カウントアップ
    set /A ICNT=!ICNT!+1

    @rem データレコード出力
    @echo %%j>> "%TFILE001%"

    @rem 出力レコード件数カウントアップ
    set /A OCNT=!OCNT!+1

  )

  @rem 入力レコード件数表示
  @echo   I-FILE [ %%i ] !ICNT!件 ※ヘッダーレコード除く
)

@rem 出力レコード件数表示
@echo   O-FILE [ %TFILEID001% ] %OCNT%件

@rem 遅延環境変数無効
endlocal
@rem change-add-end 002  2025.03.15  S.Takaaze  処理件数表示追加対応

①出力レコードカウンター初期化
「set OCNT=0」で出力レコードの件数を格納する変数「OCNT」にゼロをセットして初期化します。


②遅延環境変数有効
「setlocal enabledelayedexpansion」で遅延環境変数を有効にします。
バッチスクリプトではfor文の中で変数の値編集を行う場合、この記述が無いと正しく反映されないので記述します。
for文の中で変数の値の編集、参照を行う場合の決まり事と思っておけば良いです。


③入力レコードカウンター初期化
「set ICNT=0」で入力レコードの件数を格納する変数「ICNT」にゼロをセットして初期化します。
このバッチスクリプトは、複数の入力ファイルにも対応する処理になっているので入力ファイル毎に件数を出力する為に、ひとつ目のfor文とふたつ目のfor文の間で入力レコードカウンターを初期化します。


④入力レコード件数カウントアップ
「set /A ICNT=!ICNT!+1」で入力レコード件数を格納する変数「ICNT」に1を加算してセットします。
入力ファイルを読み込んだ件数なので、ファイル読み込みが行われるふたつ目のfor文の直後に入力レコードカウンターに1を加算します。
for文内の変数利用なので「%」で囲った「%ICNT%」ではなく「!」で囲った「!ICNT!」で記述であることに注意です。


⑤出力レコード件数カウントアップ
「set /A OCNT=!OCNT!+1」で出力レコード件数を格納する変数「OCNT」に1を加算してセットします。
出力ファイルにレコードを出力した件数なので、「@echo %%j>> “%TFILE001%”」でレコードを出力した直後に出力レコードカウンターに1を加算します。
for文内の変数利用なので「%」で囲った「%OCNT%」ではなく「!」で囲った「!OCNT!」で記述であることに注意です。


⑥入力レコード件数表示
「@echo I-FILE [ %%i ] !ICNT!件 ※ヘッダーレコード除く」で入力レコードの件数を表示します。
入力ファイル毎に件数を表示する為に、ふたつ目のfor文が終わった直後にechoでメッセージ表示します。また、どの入力ファイルの件数か分かるよう「 %%i」で入力のファイル名も合わせて表示します。


⑦出力レコード件数表示
「@echo O-FILE [ %TFILEID001% ] %OCNT%件」で出力レコードの件数を表示します。
入力ファイルは複数ある場合がありますが、出力ファイルは1個だけなので、二つのfor文の両方が完了した直後にechoでメッセージ表示します。
for文の外にでているので、変数利用の記述が「%」で囲った「%OCNT%」で記述します。


⑧遅延環境変数無効
for文の処理が終了したので「endlocal」で遅延環境変数を無効にしておきます。



[修正箇所4]

@rem add-sta 002  2025.03.15  S.Takaaze  処理件数表示追加対応
@rem 処理終了メッセージ表示
echo %BATCH_ID% 処理終了

@rem 表示メッセージ確認の為、処理一時停止
pause

@rem add-end 002  2025.03.15  S.Takaaze  処理件数表示追加対応

①処理件数を表示するにあたってメッセージを見やすくする為、「echo」で処理終了メッセージの表示を追加します。
②プロンプト上にメッセージを表示するので、メッセージ確認の為に「pause」で処理を一時停止します。




4.実行結果確認

修正したバッチスクリプトを実行して追加した処理が正しく機能しているか。
また、修正前の処理が正しく機能しているかを確認します。


4-1.処理実行

①修正後のバッチスクリプト「HeaderExclusion.bat」をダブルクリックして実行します。




②コマンドプロンプト上に表示されるメッセージを確認します。

・処理開始メッセージ、処理終了メッセージが表示されていることを確認
・入力ファイルの件数が入力ファイル毎に表示されていることを確認
・出力ファイルの件数が表示されていることを確認



4-2.処理結果比較

今回の修正はメッセージ表示機能を追加しただけで、出力されるファイル自体は修正前と同じにならなければいけません。

修正前のバッチスクリプトと修正後のバッチスクリプトそれぞれで同じ入力ファイルを使用して処理を実行し、修正前処理の出力ファイルと修正後の出力ファイルを比較した結果、完全一致することを確認します。

ファイルの比較には「comp」コマンドを利用します。
ファイルを比較して完全一致しているかどうかを確認できます。

[ compコマンド結果 ]

比較した結果、出力ファイルは修正前後で完全一致していることを確認できました。




5.おわりに

処理件数というのはなにかとチェックする機会のあるもので、できればついているとありがたいです。
ひとつの例ですが、プログラム一個ならファイルを数珠繋ぎで使用するジョブの連続実行など、最後の処理で出力ファイルが作成されデータが書き込まれているはずが0件でファイル作成された時、どのタイミングで0件になっているかを追うことができます。

また、本番稼働時の稼働チェックの1項目として各処理時点の件数を確認シートに記入することもあります。その際に件数をカウントするロジックの無いプログラムがあった場合は、ファイルを開いて件数を確認していました。これが結構手間です。

Linux系ならwcコマンドの-lオプション、Windowsならfindコマンドに/Vオプションと/Cオプションを合わせてファイル内のレコード件数を取得することもできますが、厳しい現場だと本番環境上でのコマンド実行は制限されていることもあります。

中間のファイルが残ってない!とかファイルの文字コードがEBCDICだ!本番環境なのに誰か間違ってファイル消しやがった!など現場では様々な状況があるので、やっぱりプログラム自体に処理件数をカウントする処理があるとありがたいなと思います。

以上です。
宜しくお願い致します。



タイトルとURLをコピーしました