Just another IT site ※IT系の記事は当方環境での実施内容となるため実施する場合は自己責任でお願いいたします。At Your Own Risk!! TURN BACK WHILE YOU CAN
PR

「CSVファイルを1行ずつ読み込んで、カンマ区切りで要素を分解して処理する(while read 構文)」を、Windowsのバッチファイル(.bat)で再現する方法

※IT系の記事は当方環境での実施内容となるため実施する場合は自己責任でお願いいたします。スクリプトはAI生成のものも多いのでコピー&ペーストの際は文字コードに注意ください!

Linux環境でよく使われる「CSVファイルを1行ずつ読み込んで、カンマ区切りで要素を分解して処理する(while read 構文)」を、Windowsのバッチファイル(.bat)で再現する方法です。

 

スポンサーリンク
バッチ処理の自動化スキルは市場価値が高いです。今の自分の単価を調べてみませんか?
顧客常駐はもう嫌だ!社内SEへ転職するなら【社内SE転職ナビ】
Cursor・Claude Code・Codex AIスキルを学ぶなら
環境構築不要!AIエージェント開発を非エンジニアでも即実践【AI Agent Camp】

1. 元にするLinux(Bash)のコード

まずは、今回Windows版に移植したい元ネタのコードを確認しておきましょう。

Bash

while IFS=, read -r -a HAIRETSU; do
    # 配列の各要素にアクセスして処理を記述
    echo "第1フィールド: ${HAIRETSU[0]}"
    echo "第2フィールド: ${HAIRETSU[1]}"
done < input.csv

カンマ(,)を区切り文字(IFS)に指定して、行を配列 HAIRETSU に格納していく定番の書き方ですね。

これをWindowsバッチでやろうとすると……実はバッチファイルには「本当の意味での配列変数」が存在しません。 そのため、ちょっとした「バッチ特有のコツ」が必要になります。

2. Windowsバッチ版の完成コード

結論から言うと、Windowsでは FOR /F コマンドを使うのが正解です。完成したコードがこちら!

DOS

@echo off
chcp 65001 > nul
setlocal enabledelayedexpansion

:: 読み込むCSVファイルを指定
set "INPUT_FILE=input.csv"

:: ファイルが存在しない場合はエラー終了
if not exist "%INPUT_FILE%" (
    echo エラー: %INPUT_FILE% が見つかりません。
    exit /b 1
)

:: FOR文でファイルを1行ずつ読み込み、カンマ(,)で分割
for /f "usebackq tokens=1,2 delims=," %%a in ("%INPUT_FILE%") do (
    :: %%a が第1フィールド、%%b が第2フィールドに対応
    set "FIELD1=%%a"
    set "FIELD2=%%b"

    :: ここに各要素を使った処理を記述
    echo1フィールド: !FIELD1!
    echo2フィールド: !FIELD2!
)

endlocal
pause

3. コードの解説(ここがポイント!)

Linux版からWindows版へ移植するにあたり、重要なポイントを3つに絞って解説します。

① 配列の代わりは「アルファベット順の変数」

バッチファイルでは tokens=1,2 delims=, というオプションを使います。

  • delims=, :カンマで区切るよ!という指定(Bashの IFS=,

  • tokens=1,2 :1番目と2番目の要素を取り出すよ!という指定

ここで基準となる変数を %%a に設定すると、自動的に %%b に2番目の要素が割り当てられます。(3番目があれば %%c になります)。 これがBashでいう ${HAIRETSU[0]}${HAIRETSU[1]} の代わりになります。

② ループ内の変数表示は % ではなく !

バッチファイルの最大の罠がここです。 通常のバッチでは変数を %FIELD1% のように囲みますが、FOR文(ループ)の中で中身がどんどん変わる変数を扱うときは、!FIELD1! のように !(びっくりマーク)で囲む必要があります。 これを使うために、冒頭で setlocal enabledelayedexpansion(遅延環境変数の有効化)というおまじないを書いています。

③ 文字化け対策の chcp 65001

もし読み込むCSVファイルが「UTF-8」で保存されている場合、Windowsバッチは高確率で文字化けします。 冒頭の chcp 65001 > nul は、バッチの文字コードを一時的にUTF-8に変更するコマンドです。これを入れておけば日本語が含まれるCSVでも安心です!(※CSVがShift-JISの場合は、この行を削除してくださいね)

まとめ

Linuxの while read は、Windowsバッチでは FOR /F "tokens=... delims=..." に化けます。

ちょっと癖のあるWindowsバッチですが、このパターンさえ覚えてしまえばCSVパース(解析)の自動化タスクも怖くありません。サーバーの移行作業や、クロスプラットフォームでのスクリプト運用の参考にしてみてください!

※おまけ

自動で変数が増えていく仕組み

FOR /F 文の中で指定する %%a は、あくまで「スタート地点の文字」という扱いになります。

コードの中で tokens=1,2(1番目と2番目の要素を取る)と指定した場合、バッチファイルは裏側で次のように自動割り当てを行います。

  1. 1番目の要素 = 指定した %%a に入る

  2. 2番目の要素 = アルファベット順で次の %%b に自動で入る

もしこれが tokens=1,2,3,4 であれば、コードに書いていなくても %%a%%b%%c%%d の4つの変数が自動的に使えるようになります。

⚠️ 使うときの注意点(バッチの罠)

この仕組みがあるため、バッチファイルを書くときは以下の2点に注意する必要があります。

① 大文字と小文字は区別される

スタート地点を小文字の %%a にした場合、自動生成されるのも小文字の %%b です。大文字で %%B と書くと別物とみなされて動かなくなります。

② アルファベットの「追い越し」に注意

もし tokens の数が多くて、変数名が %%z を超えてしまうと、それ以降の要素は正しく処理できなくなります。 また、スタート地点を %%x などにしてしまうと、%%x, %%y, %%z の3つまでしか自動生成できません。そのため、基本的にはスタート地点を %%a%%i などの若いアルファベットにしておくのが鉄則です。

もし「変数名が自動で変わるのが気持ち悪い」ときは?

%%b%%c をそのままコードの中で何度も使うと、どれが何のデータか分かりにくくなってしまいますよね。

そのため、ブログ風記事のコードでもやっていたように、ループの先頭で分かりやすい名前の変数にコピーしてあげるのが、バッチファイルを綺麗に書くコツです。

DOS

:: %%a%%b を、分かりやすい変数名に入れ直す
set "FIELD1=%%a"
set "FIELD2=%%b"

:: 以降の処理は、この分かりやすい変数名を使う
echo1フィールドは !FIELD1! です

このように、%%b は「データを取り出すためだけの使い捨ての窓口」として割り切って使うと、スクリプトがすっきりして読みやすくなりますよ!

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