0

I ran across an issue using the SET command inside a FOR /F loop to echo the values of the loop parameters (e.g., %%g, %%h, etc.). I used the SET command because I wanted to see what values get assigned to each FOR /F loop parameter when the FOR /F loop iterates. I am specifically looking to see how many caret escape characters (^) are stripped by the CMD parser as it processes the line of test code that is the last element in the $code_test[00] array record:

@echo off

setlocal disabledelayedexpansion

set $code_test[00]=Record [00],2,green,blue,if not exist ^^!$m^^!^^!$n^^! (set /a $result+=3)

echo Value using ECHO command:
echo $code_test[00] = %$code_test[00]%
echo.

echo Value using SET command with Delayed Expansion DISABLED:
set $code_test[
echo.

setlocal enabledelayedexpansion

echo Value using SET command with Delayed Expansion ENABLED:
set $code_test[
echo.

for /f "tokens=1-10 delims=," %%g in ('set $code_test[') do (

    echo For /f loop values using ECHO command ...
    echo g = %%g
    echo h = %%h
    echo i = %%i
    echo j = %%j
    echo k = %%k
    echo.

    echo For /f loop values using SET command ...
    set %%g
    set %%h
    set %%i
    set %%j
    set %%k

)

The code populates one record for the $code_test[xx] array with various elements, the last of which is a Windows CMD test code statement. I want to see the value of the FOR /F loop parameter that corresponds to this test code statement, which is %%k. So, I used both the echo and set commands to echo the value of %%k to see if %%k retained the caret (^) escape characters that were present in the original test code definition for $code_test[00]. The echo command worked as expected and stripped the caret escape characters (^) from the code. But the set command completely failed. I've read the post about how the CMD interpreter parses code here and I didn't see an answer to my question.

I realize that dealing with FOR /F loop parameters can be tricky. Should I just assume that I can't deal with FOR /F loop parameters directly (e.g., set %%k) and make it a policy to always assign the value of a FOR /F parameter to an environment variable then deal with the environment variable instead of the FOR /F parameter?

Bill Vallance
  • 471
  • 3
  • 19
  • 2
    You have a fundamental error here. `%%k` is a for parameter. Suppose that `%%k` is "green". Then, `echo %%k` show _the value_ of `%%k`, so it show "green". `set varName` command show the value of _a variable_. In this way, `set %%k` would show the value of a variable called "green", if such a variable exists... A for parameter (like `%%k`) is _very different_ than an environment variable (like `%k%`). You always can manage a for parameter directly. If you _prefer_ to asign it to a variable, then you need to use `!delayedExpansion!` in order to manage the variable. – Aacini Jul 12 '19 at 16:50
  • Thanks, @Aacini, for the quick reply. Now I understand why the `set` command works the way it does with FOR parameters. This is REALLY helpful. If you wouldn't mind posting your reply as an answer I'll give you the credit. – Bill Vallance Jul 12 '19 at 17:44

1 Answers1

0
SET "blue62=108"
SET "%%%%k=hello"
ECHO after SET %%%%%%%% k errorlevel=!errorlevel!
set|FIND "k="

    echo For /f loop values using SET command ...
ECHO ++++++++++++++++!errorlevel!
    set %%g
    set %%h
    set %%i
    set %%j
ECHO :::::::::::::::::::::!errorlevel!
    SET if not exist !$m!!$n! (set /a $result+=3)
ECHO -----------!errorlevel!-------------------
ECHO :::::::::::::::::::::!errorlevel!
    SET "if not exist !$m!!$n! (set /a $result+=3)"
ECHO -----------!errorlevel!-------------------
    set %%k

)

I expanded your reporting to include the above code with these results:

For /f loop values using ECHO command ...
g = $code_test[00]=Record [00]
h = 2
i = green
j = blue
k = if not exist !$m!!$n! (set /a $result+=3)

after SET %%%% k errorlevel=0
For /f loop values using SET command ...
++++++++++++++++1
Environment variable 2 not defined
Environment variable green not defined
blue62=108
:::::::::::::::::::::1
-----------1-------------------
:::::::::::::::::::::1
-----------1------------------- Environment variable %k not defined

I believe this demonstrates that set simply acts strangely if confronted with an argument that is not a simple space-absent string with optional = for assignment.

What was really curious was that the Environment variable %k not defined did not appear with the original code.

I believe you're really expecting a 1970's vintage design to not only be bullet-proof but act in a consistent manner when supplied with unanticipated data. Just treat it like your grandma. Very capable, but easily confused.

Magoo
  • 77,302
  • 8
  • 62
  • 84