【バッチスクリプト】CSVファイルから特定のレコードを抽出して出力する

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

今回はCSVファイルを読み込んで、特定のレコードのみ抽出してファイル出力する処理です。


1.はじめに

CSVファイルを読み込んで、特定のレコードのみ抽出してファイル出力する処理です。
今回は具体例として以下のように入力ファイルから条件に合致したレコードのみ出力ファイルへ出力します。

条件としては「証券コード」項目が「9997」のレコードを抽出します。



2.使用コマンド

特定項目の抽出には「for」コマンドにより行います。

以下、forコマンドのヘルプ(コマンド「for /?」の実行結果)より一部抜粋

FOR /F "eol=; tokens=2,3* delims=, " %i in (myfile.txt) do @echo %i %j %k

  この例は、myfile.txt の各行を解析します。セミコロンで始まる行を無視し、
  各行の 2 番目と 3 番目のトークンを for 本体に渡します。
  トークンは、コンマまたはスペースで区切られています。
  %k で 3 番目以降のすべてのトークンを取得していることに
  注意してください。
  スペースを含むファイル名に対しては、二重引用符でファイル名を引用する
  必要があります。
  この方法で二重引用符を使うためには、usebackq オプションも
  使わなければなりません。
  使わなければ、二重引用符はリテラル文字列の定義として
  解釈され、解析されます。

  %i は for 文で明示的に宣言され、%j と %k は tokens= オプションで暗黙的に
  宣言されています。
  tokens= 行を使って 26 個までのトークンを指定できますが、
  文字 'z' または 'Z' よりも高い変数を宣言することはできません。FOR 変数名は
  単一の文字で、大文字と小文字を区別し、グローバルなものであり、一度に
  アクティブにできるのは合計 52 個までです。

ヘルプの記載を参考に今回は以下のコマンドとなります。

[ コマンド例 ]

for /F "usebackq tokens=1* delims= " %%a in ("入力ファイル") do (
    @echo %%a %%b>> "%OFILE001%"
)

・tokensに指定している「1*」(1とアスタリスク)は、読み込んだCSVの1項目を1番目のトークン「%%a」に渡して残りの項目すべてを2番目のトークン「%%b」に渡します。
・delims(区切り文字)は見かけ上スペースに見えますが、タブを指定しています。



3.作成スクリプト

3-1.コード内容

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

[ RecordExtraction.bat ]

@echo off
@rem ------------------------------------------------------------
@rem システム名         : RfromL.com
@rem 処理ID             : RecordExtraction
@rem 処理名             : レコード抽出処理
@rem 処理内容           : 証券コード「9997」のレコードを
@rem                    : 抽出して出力
@rem 作成日             : 2025.03.19
@rem 作成者             : S.Takaaze
@rem パラメータ         : なし
@rem 備考               : 
@rem 
@rem *** 修正履歴 ***********************************************
@rem No.  日付        修正者              内容
@rem 001  2025.03.19  S.Takaaze  新規作成
@rem ------------------------------------------------------------
@rem - 初期処理
@rem ------------------------------------------------------------
@rem 実行バッチファイルディレクトリ設定
set CMD_PATH=%~dp0

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

@rem 処理開始メッセージ表示
echo %BATCH_ID% %DATE:~0,4%年%DATE:~5,2%月%DATE:~8,2%日 %TIME:~0,2%時%TIME:~3,2%分%TIME:~6,2%秒 処理開始

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

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

@rem ------------------------------------------------------------
@rem - ファイルID設定
@rem ------------------------------------------------------------
@rem 入力ファイルID
set IFILEID001=INFILE.txt

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

@rem ------------------------------------------------------------
@rem - ファイル設定
@rem ------------------------------------------------------------
@rem 入力ファイル
set IFILE001=%IDIR%\%IFILEID001%

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

@rem ------------------------------------------------------------
@rem - 前処理 : 出力ファイルクリア処理
@rem ------------------------------------------------------------
if exist "%OFILE001%" del "%OFILE001%"

@rem ------------------------------------------------------------
@rem - レコード抽出
@rem ------------------------------------------------------------
@rem 遅延環境変数有効
setlocal enabledelayedexpansion

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

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

@rem 入力ファイル読込
for /F "usebackq tokens=1* delims= " %%a in ("%IFILE001%") do (
  @rem 入力レコード件数カウントアップ
  set /A ICNT=!ICNT!+1

  if %%a == 9997 (

    @rem データレコード出力
    @echo %%a %%b>> "%OFILE001%"

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

@rem 入力レコード件数表示(頭ゼロ埋め10桁)
set ZEROPAD-ICNT=000000000!ICNT!
@echo   I-FILE !ZEROPAD-ICNT:~-10!件 [ %IFILEID001% ]

@rem 出力レコード件数表示(頭ゼロ埋め10桁)
set ZEROPAD-OCNT=000000000%OCNT%
@echo   O-FILE %ZEROPAD-OCNT:~-10%件 [ %OFILEID001% ]

@rem 遅延環境変数無効
endlocal

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

@rem 処理終了メッセージ表示
echo %BATCH_ID% %DATE:~0,4%年%DATE:~5,2%月%DATE:~8,2%日 %TIME:~0,2%時%TIME:~3,2%分%TIME:~6,2%秒 正常終了

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

exit /b 0

※メッセージを確認するため、正常終了処理、異常終了処理のブロックに「pause」を記載して処理を一時停止するようにしています。


3-2.ディレクトリ構成

作成したバッチスクリプトを実行する際のディレクトリ構成です。

3-3.入力ファイル仕様

[ ファイル項目 ]

区切り文字:タブ
改行コード:CRLF
文字コード:S-JIS


3-4.入力ファイル内容

テストに使用するファイルの内容です。

3-5.出力ファイル仕様

※入力ファイルと同様

[ ファイル項目 ]

区切り文字:タブ
改行コード:CRLF
文字コード:S-JIS


3-6.機能説明

①ディレクトリ「IN」配下に格納されたファイル「INFILE.txt」を読み込む。
②入力ファイルのレコード数ぶん以下 a.~c. の処理を繰り返す。
 a.入力レコード件数をカウントアップする。
 b.入力ファイルから以下の条件に一致したレコードを出力する。
   項目「証券コード」が「9997」
 c.出力レコード件数をカウントアップする。

③入力レコード件数を表示する。
④出力レコード件数を表示する。



4.実行結果確認

①入力ファイルの内容を確認




②ファイル出力先のディレクトリにファイルがなにも無いことを確認。




③バッチスクリプトをダブルクリックして実行




④表示されたメッセージから処理が実行されていることを確認




⑤出力ファイルの内容を確認

入力ファイルから「証券コード」が「9997」のレコードが出力されていることを確認。



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


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