2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

記事投稿キャンペーン 「2024年!初アウトプットをしよう」

バッチファイルでiniファイルを読み込む(セクション対応)

Posted at

バッチファイルでいい感じにINIファイルを読めたのでメモ。

SETLOCAL ENABLEDELAYEDEXPANSION
SET SET_COMMAND=
SET PREFIX=
FOR /F "usebackq tokens=*" %%I IN (config.ini) DO (
    SET LINE=%%I
    ECHO !LINE! | FINDSTR /B [ >NUL
    IF ERRORLEVEL 1 (
        SET SET_COMMAND=!SET_COMMAND!^^^&SET !PREFIX!%%I
    ) ELSE (
        SET PREFIX=!LINE:~1,-1!_
    )
)
REM ERRORLEVELを元に戻す
DIR >NUL
ENDLOCAL %SET_COMMAND%

こんな config.ini を用意してると、

[SECTION1]
ENTRY1=valu1-1
ENTRY2=valu1-2
ENTRY3=valu1-3

[SECTION2]
ENTRY1=value2-1
ENTRY2=value2-2

こんな風に読み込める。

>set
...
SECTION1_ENTRY1=valu1-1
SECTION1_ENTRY2=valu1-2
SECTION1_ENTRY3=valu1-3
SECTION2_ENTRY1=value2-1
SECTION2_ENTRY2=value2-2
...

ポイントは2つ。

ポイント1つ目。
このコード、最後に FINDSTR が失敗して終わるので、コード実行後に ERRORLEVEL1 になり、バッチファイル呼び出し元でエラー判定しちゃうってことになってしまった。
そこで、最後に DIR >NULERRORLEVEL を戻してあげている。

ポイント2つ目。
環境変数の遅延展開を使いたいけど、そうするとendlocal以降に環境変数を持ち出せなくなってしまう。
最初は呼び出し元で setlocal enabledelayedexpansion を呼び出さないといけない縛りを付ける方向でかんがえてたんだけど、実はendlocal以降に変数を持ち出す裏技があるらしい。
リンク先の技そのままだと、環境変数名がわかってる必要があるけれど、今回はINIファイル次第で変数名も数も変わるのでそのままでは書きづらい。
ということで、

&SET SECTION1_ENTRY1=value1-1&SET SECTION1_ENTRY2=value1-2...

みたいな文字列を作って endlocal の後ろに置いてみたらいい感じにエクスポートできた。

ただし、この変数を組み立てるときに

SET SET_COMMAND=!SET_COMMAND!&SET !PREFIX!%%I

としたところ、SET SET_COMMAND=!SET_COMMAND!SET !PREFIX!%%I が別コマンドとみなされて玉砕。

SET SET_COMMAND=!SET_COMMAND!^&SET !PREFIX!%%I

これでもうまくいかなくて(!SET_COMMAND!の展開時にコマンド分割された?)、

SET SET_COMMAND=!SET_COMMAND!^^^&SET !PREFIX!%%I

で最初のハットもエスケープしてあげたらうまくいった。

まあなんだかんだいい感じにできてよかったw

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?