Alright, I tend to call something like this as "nested variables". Anyway, to expand such nested variables, you need to establish a second parsing or expansion phase, and you need to ensure that the inner variable (POS
) becomes expanded first, and the outer one (OLD_ENTRY
) becomes expanded during the second phase. There are some options:
Using call
:
This option avoids delayed variable expansion, which could be problematic with literal !
symbols, but it is quite slow, and it doubles quoted ^
characters:
In command prompt window:
call echo %^OLD_ENTRY:~0,%POS%%
This looks like "escaping" (^
) the outer variable, but actually, this has got nothing to do with true escaping. In command prompt, an undefined variable does not become replaced by an empty string, it is just kept literally. So in the first pass, the undefined variable ^OLD_ENTRY
is simply kept (you can verify that by defining such a variable by set "^OLD_ENTRY=something"
), scanning for the closing %
is skipped after the :
for undefined variables strangely, the variable %POS%
becomes expanded, and the last (orphaned) %
is kept too; immediately after this phase, the escape sequence ^O
is recognised, which results in a literal O
; so we get echo %OLD_ENTRY:~0,33%
, which becomes expanded in the second pass.
In a batch file:
call echo %%OLD_ENTRY:~0,%POS%%%
In the first pass, the first two consecutive percent symbols become replaced by one literal %
sign, the variable %POS%
becomes expanded, and the remaining two consecutive percent symbols become replaced by one literal %
sign too, so we have echo %OLD_ENTRY:~0,33%
, which becomes expanded in the second pass.
Using delayed variable expansion:
This is the better option, I think, because it is faster and does not mess around with ^
:
echo !OLD_ENTRY:~0,%POS%!
This option works in both command prompt window and batch files. Here the first pass is the normal/immediate expanssion (%
) which handles the %POS%
variable, so the second pass the delayed expansion (!
) receives echo !OLD_ENTRY:~0,33!
to expand.
Refer also to this post: How does the Windows Command Interpreter (CMD.EXE) parse scripts?