batファイルにてfor文が正常に動作しないので理由を知りたいです。

forやifなどの構造を持った文は、実行に先立って環境変数が展開されます。簡単な例だと、

CMD

1set A=@ 2for %%X in (A B C D) do ( 3 set A=%A%-%%X 4)

のfor文は、for文の直前のAの値を展開して、

CMD

1for %%X in (A B C D) do ( 2 set A=@-%%X 3)

として実行され、Aの値は最終的に@-Dになります。

対応策は色々ありますが、例えば下記のようにforの外に処理を出します。

CMD

1set SRCFILE=TEST.bat 2set RENAMEDIR=renamedir 3 4for %%a in ('dir /b %RENAMEDIR%\*.txt') do call :SUB %%A 5exit /b 6 7:SUB 8set DSTFILE=%1 9copy %SRCFILE% %DSTFILE:~0,-4%.bat 10exit /b

他には、 変数の値の参照を、そのコマンド実行時点にまで遅延させる遅延環境変数展開の機能を使うか。
setlocal enabledelayedexpansion!

CMD

1setlocal enabledelayedexpansion 2 3set SRCFILE=TEST.bat 4set RENAMEDIR=renamedir 5 6for %%a in ('dir /b %RENAMEDIR%\*.txt') do ( 7 set DSTFILE=%%a 8 copy %SRCFILE% !DSTFILE:~0,-4!.bat 9)

ただ、この場合に限定すれば、拡張子を取る処理をするだけなので、どちらも不要です。
%%~n変数で、拡張子を除いたファイル名になります。この記法一覧は、for /?の末尾にあります。

CMD

1set SRCFILE=TEST.bat 2set RENAMEDIR=renamedir 3 4for %%a in ('dir /b %RENAMEDIR%\*.txt') do ( 5 copy %SRCFILE% %%~na.bat 6)

ちょっと見にくいので普通はfor変数は大文字を使います。

コメントを投稿

0 コメント