Help us understand the problem. What is going on with this article?

環境遅延変数の原因と2つのポイント

概要

最近、for文でがっつりはまりました。。。

以下のfor文はファイルの中身を1行ずつ読み取り、
full_nameをechoするもの。この例センスない...
hoge.txtの中身は
image.png

read.bat
@echo off
set name=hoge
for /f %%a in (hoge.txt) do (
    set full_name=%%a%name%
    echo %full_name%
)

これを実行すると、以下のような結果となります。
image.png

このメッセージ「ECHOはOFFです。」はECHOした変数が初期化されているときに出力されるメッセージです。
つまり、変数full_nameは初期化状態のまま、出力されているということになります。
これが謎でした...

原因

この原因は、変数を読み込むタイミングが問題でした。
%で囲まれた変数はその行の読み始めで展開される
()で囲まれたコマンドは1行とみなされる
のです。まじ謎。
つまり、何度for文を回そうとも、full_nameが初期化状態でechoされていたのです。

環境遅延変数

これを解決するのが、環境遅延変数です。
環境遅延変数とは、変数を読み込むタイミングを遅延させることができる変数で以下のように表します。

  1. 変数を%で囲わず、!で囲む
  2. setlocal enabledelayedexpansionを書く

修正したread.batはこちら

read.bat
@echo off
setlocal enabledelayedexpansion

set name=hoge
for /f %%a in (C:\work\hogehoge\hoge.txt) do (
    set full_name=%%a%name%
    echo !full_name!
)

実行結果は以下のようになり、full_nameが変更されて出力されています。
image.png

まとめ

通常、変数を読み込むタイミングは
その行の読み始めで、()で囲まれたコマンドは1行とみなされる

環境遅延変数を用いれば、このタイミングを直前に変更でき、その方法は
1. ()で囲まれたコマンドは1行とみなされる
2. setlocal enabledelayedexpansionを書く

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away