« NASAが39光年先に7つの地球型惑星を発見と発表!! | トップページ | あるiPadに施された”アドブロック”があまりにロー・・・ハイテクで話題に! »

2017年2月25日 (土)

Windowsのバッチファイルでfor文で変数を変えながら繰り返し処理をするときの注意点

わかりにくいタイトルですいません。

会社で、こんなような処理をさせたくてバッチファイルを組んでたんですが、なかなかうまいこと動かずに苦労しました。

Bat_for01

例えば「C:\tmp\data」のフォルダの下にこんな感じのフォルダがずらっと並んでいたとします。

このフォルダの中に、それぞれのフォルダ名を使ったテキストファイル(正確にはスクリプトファイルですが)を作りたかったんですが、そのテキスト内には

・ 自身のフォルダ名(”c01a001”)を書き込む部分

・ 自身のフォルダ名の後ろ3文字だけ(”001”)切り出して書き込む部分

があります。

そこで、こんなバッチファイルを作ったんですけど。

@echo off
for /d %%A in (C:\tmp\data\*.*) do (
   set B=%%~nA
   set C=%B:~4,3%
   echo %C% > %%A\%B%.txt
   echo %B% >> %%A\%B%.txt
)

このバッチファイルで期待した出力結果は、例えば「c01a002」ってフォルダの中に

002
c01a002

という内容の、「c01a002.txt」という名前のテキストファイルを作るというもの。

「c01a001」なら1行目が”001”に、2行目が”c01a001”になります。

ところが実際にこれを実行すると、すべてのフォルダに「c02a003.txt」という名前の

003
c02a003

という中身のファイルばかりが生成されます。

つまり”set”で定義した変数(B、C)が一番後ろのフォルダ名のものだけ出てきてしまうというもの。

どうやらfor文の( )内にあるset文の内容は、そのfor文の( )内の一番最後の処理で出てきた変数で置き換えられてしまうようです。

こういうのを「遅延環境変数の即時展開」っていうそうです。

で、for文の中でset文で定義した変数を変えながら繰り返し処理をさせたい場合は「遅延環境変数の展開」ってやつを行わなきゃいけないそうです。

CMD.EXEの遅延環境変数の展開 - ふなWiki

もはや何を言っているのかわかりませんが・・・日本語でおK?

上のバッチファイルを修正したものは以下の通り。

@echo off
setlocal enabledelayedexpansion
for /d %%A in (C:\tmp\data\*.*) do (
   set B=%%~nA
   set C=!B:~4,3!
   echo !C! > %%A\!B!.txt
   echo !B! >> %%A\!B!.txt
)

変えたところは大きく2箇所。

まず、for文の前に「setlocal enabledelayedexpansion」ていう呪文を入れます。これが「遅延環境変数の展開」ってやつだそうで。

そして、set文で定義した変数をfor文内で使うときは「!」で囲います。変数Bなら「!B!」って具合に。

これで、フォルダ名が「c01a001」なら1行目に”001”、2行目に”c01a001”と書かれた「c01a001.txt」という名前のテキストファイルが、フォルダ名が「c01a002」なら1行目が”002”に・・・という具合に、フォルダごとに独自の内容・名前のテキストファイルが順次生成されます。

たったこれだけの処理をさせるだけなのに、ずいぶん時間かかっちゃいました。

コマンドプロンプトってえのはLinuxのようにはいきませんね。

賢くなったと喜ぶべきか、Windowsのコマンドプロンプトの面倒臭さに嘆くべきか・・・Windows 10だったらまっさきにBash on Windowsを入れてやりたいところですね。

[改訂新版]Windowsコマンドプロンプトポケットリファレンス

« NASAが39光年先に7つの地球型惑星を発見と発表!! | トップページ | あるiPadに施された”アドブロック”があまりにロー・・・ハイテクで話題に! »

パソコン系」カテゴリの記事

コメント

人それぞれ使いやすい道具を使う
だけですが、私だったらエクセルなどの
マクロを使ってモリモリやってますね。
マクロ信者だったので(w

こんにちは、mokekyoさん。

Excelマクロも考えたんですが、このあとコマンドで呼び出すアプリケーションのことを考えるとバッチファイルで記述したほうが好都合だったので、頑張って書きました。私も普段はマクロ、VBA派、時々Pythonです。

コメントを書く

(ウェブ上には掲載しません)

トラックバック

« NASAが39光年先に7つの地球型惑星を発見と発表!! | トップページ | あるiPadに施された”アドブロック”があまりにロー・・・ハイテクで話題に! »

無料ブログはココログ

スポンサード リンク

ブログ村