0

I need to output the first X characters of the content of OLD_ENTRY, say 33 chars. I grab the number of chars with another script. What is, in the following command in a Windows cmd script, the correct syntax to use a variable, say POS, instead of the hardcoded value 33?

echo %OLD_ENTRY:~0,33%

Thanks for any help,

Rip

user1030520
  • 154
  • 1
  • 13
  • 2
    `call echo %^OLD_ENTRY:~0,%POS%%` (in command prompt window) or `call echo %%OLD_ENTRY:~0,%POS%%%` (in batch file), or, if [delayed variable expansion](http://ss64.com/nt/delayedexpansion.html) is enabled, `echo !OLD_ENTRY:~0,%POS%!` (in both)... – aschipfl Apr 04 '18 at 14:41
  • Cmd.exe shell script (batch) is full of these arcane quirks. Switch to PowerShell instead. – Bill_Stewart May 09 '18 at 21:37
  • Yeah, but arcane quirks make programmer's life more fun, alas in fairness a little less productive too! – user1030520 May 11 '18 at 06:44

1 Answers1

1

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:

  1. 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:

    1. 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.

    2. 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.

  2. 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?

aschipfl
  • 33,626
  • 12
  • 54
  • 99