Windowsバッチファイル外部ファイルの読み書き

バッチファイルでのファイル読み書きについて

Windowsバッチファイルには外部ファイルを読み書きする十分な機能が用意されていません。

ファイル操作に用いることができる機能としては、リダイレクト機能とfor文のみとなります。

バッチファイルファイルで作り込むよりも、ファイル操作を行う処理をWSH(VBScriptやJScript)またはPowerShellなどのスクリプトで作成しておき、それを呼び出す方法を採用した方が簡単な場合があります。


バッチファイルのリダイレクト

標準出力のリダイレクト

コマンド実行結果の標準出力(stdout)をファイルに出力するには、下記の指定を行います。


コマンド 1> ファイル名

出力先としてファイル名を指定した場合、指定したファイルが存在しない場合はファイルを新規に作成した上で出力を行います。

なお、「1」は標準出力(stdout)の指定であり、省略された場合にも「1」が指定されたものと見なします。下記のように記述することも可能です。


コマンド > ファイル名

既に存在するファイルに対して追記する場合には下記形式となります。


コマンド >> ファイル名

標準エラー出力のリダイレクト

コマンド実行結果の標準エラー出力(stderr)をファイルに出力するには、下記の指定を行います。


コマンド 2> ファイル名

標準出力と標準エラー出力の両方をファイルへ出力する場合には、下記の指定を行います。


コマンド > ファイル名 2>&1

出力を全て破棄する場合には、nullデバイスを指定します。


コマンド > nul 2>&1

ファイル内容を標準入力する

コマンドに対してファイルの内容を渡します。


コマンド < ファイル名

バッチファイルで外部ファイルを読み込む

設定ファイル(iniファイル)

下記設定ファイルを用意します。

なお、「;」はiniファイルにおけるコメント行の表記です。


;  comment
key1=c:\tmp\path1
key2=c:\tmp\path2
key3=c:\tmp tmp\path3

スクリプト

下記サンプルはファイル内容を環境変数に登録するスクリプトです。


for文を用いて、ファイル内容を読み取っていきます。

usebackqオプションを指定するとファイル名をダブルクォートで括ることができ、空白文字を含むファイル名でも正しく認識できます。

なお、for文は行頭の「;」をコメント行と認識するようです。


@echo off
setlocal

REM 設定ファイルパス
set CONFFILE=.\config.ini

REM 設定ファイルが存在するか確認する
if not exist %CONFFILE% (
    echo ERROR: Not found %CONFFILE%
    exit /b 1
)

REM 設定ファイルを読み込む
for /f "usebackq tokens=1,* delims==" %%a in ("%CONFFILE%") do (
    # 環境変数として登録する
    set %%a=%%b
)

REM 環境変数を参照する
echo %key3%

endlocal
exit /b 0

バッチファイルでCSVファイルを読み込む

設定ファイル(csvファイル)

下記設定ファイルを用意します。


# comment
ID,Name,Size
"001","item1",3
"002","item2",15
"003","item3",7

スクリプト

CSVファイルを読み込み、最大サイズの名前を取得するサンプルです。


列の区切り文字として「delims=,」オプションを指定することでCSVの文字列分割を行います。

また、「skip=2」を指定することで、先頭から2行分(コメント行とヘッダ行)を無視しています。


@echo off
setlocal enabledelayedexpansion

REM 設定ファイルパス
set FILENAME=.\config.csv

set buf_name=
set buf_size=

REM CSVファイルを読み込む
for /f "usebackq skip=2 tokens=1,2,3* delims=," %%i in ("%FILENAME%") do (  
    REM 最大値をバッファに保持する
    if %%~k gtr !buf_size! (
        set buf_name=%%~j
        set buf_size=%%~k
    )
)
echo %buf_name%

endlocal
exit /b 0

バッチファイルでファイルを編集する。

バッチファイルでファイルを編集することは非常に手間がかかります。

難しい文字列置換などを伴う編集を行うならば、以下のような代替機能を用いる方が簡単な場合があります。

  • 他のスクリプト言語(VBScriptやPowershellなど)で作成したスクリプトを呼び出す方法
  • sedコマンドをダウンロードして利用する方法
  • ファイル末尾にリダイレクト出力する方法

ファイル編集バッチファイルのサンプル

バッチファイルにおける変数の文字列置換は以下の形式となります。


set "str=!str:%置換元%=%置換先%!" 

以下は、ファイルを一行ずつ読み込んで置換処理を行うことで、ファイル中の文字列を置換するサンプルです。


@echo off
setlocal enabledelayedexpansion

REM 設定ファイルパス
set FILENAME=.\config.txt
set FILESWAP=.\config.txt.swap

set src=置換元
set dest=置換先

REM CSVファイルを読み込む
for /f "usebackq delims=" %%a in ("%FILENAME%") do (
    set str=%%a
    set "str=!str:%src%=%dest%!" 
    echo !str!>> %FILESWAP%
)
move /y %FILESWAP% %FILENAME%

endlocal
exit /b 0

バッチファイルでファイルのパラメータを編集する。

編集対象ファイル

コメントアウトされているパラメータが列挙されたファイルを用意します。


# config.txt
# param1=
# param2=
# param3=

# param4=
# param5=

バッチファイル

バッチファイルで空行を正しく読み込むためには工夫が必要です。

本スクリプトでは、for文に「findstr /n "^" ファイル名」コマンドを指定して、ファイルを「行番号:行本文」形式で読み込んでおき、行ごとに文字列比較処理を行っています。

編集したファイル内容は一時ファイルに保存した後、元ファイルに上書きすることで更新処理を行っています。



@echo off
setlocal enabledelayedexpansion

REM 設定ファイルパス
set FILENAME=.\config.txt

REM ファイルを編集する
set SRDWORD=# param1=
set DSTWORD=param1=id-5412
call :replace_param

REM ファイルを編集する
set SRDWORD=# param2=
set DSTWORD=param2=id-6522
call :replace_param

endlocal
exit /b 0

REM 
REM ファイルを編集する
REM 
:replace_param
    REM 一時ファイルのパス設定
    set swapfile=%FILENAME%.swap

    REM ファイルを編集する
    for /f "usebackq tokens=1* delims=:" %%a in (`findstr /n "^" %FILENAME%`) do (
        if "%%b" == "%SRDWORD%" (
            echo %DSTWORD%>>%swapfile%
        ) else (
            echo.%%b>>%swapfile%
        )
    )
    REM 一時ファイルから本ファイルへ上書きする
    move /y %swapfile% %FILENAME% >NUL 2>&1
    exit /b 0


関連ページ