2
votes

When I was testing a script I came across this issue when trying to extract characters from a string using batch. I have simplified it into a simple example. t.txt just contains the word hello.

@echo off
setlocal enabledelayedexpansion
set a=0
set b=1
for /f %%a in (t.txt) do (
set x=%%a
echo !x:~!a!,!b!!
set /a x+=1
)
pause >nul

The problem is, the variable x needs to be accessed using delayed expansion, and because I am updating the values of a and b through the loop these also need to be accessed using delayed expansion.

When trying to use the variables a and b to split the string they all need delayed expansion, but the order of the ! marks means that it is not parsed the way I intended!

CMD will expand my command as !x:~!, !,! and !!, instead of expanding the inner ones first. Obviously I can't use %'s either.

The only way I have found to get around this is to call an external function that isn't in the loop, so I can use %'s.

@echo off
setlocal enabledelayedexpansion
set a=0
set b=1
set v=
for /f %%a in (t.txt) do (
set x=%%a
call :RETURN x
set /a x+=1
)
pause >nul

:RETURN
set v=%1
echo %v:~!a!,!b!%

Is there any way of getting cmd to parse my command how I need it to, or this just a limitation I will have to use call for?

2

2 Answers

3
votes

Simply transfer variables a and b to FOR variables.

@echo off
setlocal enabledelayedexpansion
set a=0
set b=1
for /f %%a in (t.txt) do (
  set "x=%%a"
  for /f "tokens=1,2" %%A in ("%a% %b%") do echo !x:~%%A,%%B!
  REM this line makes no sense if x=hello: set /a x+=1
)
pause >nul
3
votes

Mixing delayed and normal expansion will work.

@echo off
setlocal EnableDelayedExpansion
set a=0
set b=1
for /f %%L in (t.txt) do (
  set "x=%%L"
  echo !x:~%A%,%B%!
)