user2080522
user2080522

Reputation: 11

How to split a string using values from variables? (Batch)

I have a variable that acts as a line to print, but I need to edit individual characters in that line via their position in the line. However I need to use variables to specify the location each time, and CMD interprets my variables the wrong way.

    @echo off
    set fv=0
    set fh=1
    set /a fh1=%fh%+1
    set linev=line%fv%

    set line%fv%=%linev:~0,%fh%%%NEWCHARACTER%%linev:~%fh1%%

Sorry that my code is messy, but I hope that it is understood. I want CMD to interpret the code as:
%fv% %fh% %newcharacter% %fh1% and then turn the two string manipulators into substrings.

Upvotes: 1

Views: 307

Answers (1)

Andriy M
Andriy M

Reputation: 77657

I'm not sure I understand the order of evaluation in the last line of you script sample, even with your verbal explanation. However, I think I can at least show you, using simple examples, how you can achieve what you want, and you'll work out how to apply the technique in your situation.

Basically, you need to use two kinds of expansion here: immediate (or % expansion) and delayed.

There's delayed expansion proper in batch files, which must first be enabled (typically using the command SETLOCAL EnableDelayedExpansion) and then use ! instead of % for variable evaluation. Consider the following example:

SET ind=1
SET line%ind%=ABC
SETLOCAL EnableDelayedExpansion
ECHO !line%ind%!
ENDLOCAL

In the above example, two variables are created, ind and line1. The second name is partly constructed using the first variable. When you are setting the value to such a variable, delayed expansion is not needed, because the name, left part of the assignment, doesn't need to be evaluated. But when it does need to be evaluated, you need to use delayed expansion. The ECHO command in the above script works like this:

  • %ind% is evaluated first;

  • as a result of %ind% evaluation, the command becomes ECHO !line1!;

  • since delayed expansion has just been enabled, ! now has special meaning, i.e. (delayed) variable evaluation, and so !line1! evaluates to ABC;

  • ECHO prints ABC.

Although this kind of delayed expansion is most often the preferred one, in the above example you can also achieve the same using CALL-expansion. Here's the same example script rewritten to use CALL-expansion:

SET ind=1
SET line%ind%=ABC
CALL ECHO %%line%ind%%%

Basically, there's % expansion all the way, but different parts are evaluated at different times. Here's how the second example's delayed evaluation works:

  • the first %% turns into %;

  • %ind% is evaluated to 1;

  • the remaining %% turns into %;

  • CALL now receives the command to execute: ECHO %line1%;

  • %line1% evaluates to ABC;

  • ECHO prints ABC.

The CALL expansion is slower, which may especially manifest in loops. The ! expansion, on the other hand, has some implications stemming particularly from the fact that the SETLOCAL command is used to enable the syntax. There's more on the topic in my answer to a different question.

Upvotes: 2

Related Questions