I'm going crazy for 2 days with this simple task: iterate through a 5 line string with delimiters (or a file with the same content). After I find a delimiter symbol I expect to write that line to the file, then add echo for a cr/lf representation and do next iteration for a next piece of string.
For academic purposes I recreate the code like that:
@echo off
setlocal EnableDelayedExpansion
set "LF=&echo."
set "dlm=+"
set "s1=A A A"
set "s2=B B B"
set "s3=C C C"
set "s4=D D D"
set "s5=E E E"
set "s=%s1%%dlm%%s2%%dlm%%s3%%dlm%%s4%%dlm%%s5%%dlm%"
for /f "tokens=* delims=+" %%i in ("%s%") do (
echo %%i>>test.txt
echo. >>test.txt
)
pause
The output is like:
A A A+B B B+C C C+D D D+E E E+
newline
When I want this
A A A
B B B
C C C
D D D
E E E
When I change token to 1 or 2 it returns the correct line
How to get those sub strings and write them to the file? Why tokens don't work?
I tried to put this into another loop and pass token number as !j!, but it doesn't work. I also thought of a few goto but think it's a bad practice.
The subroutine split_supplied_line
in the following batch code snippet should do the trick for (almost) any number of substrings and (almost) any delimiter. No matter whether there is a trailing delimiter.
@ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
set "LF=&echo."
set "dlm=+"
set "s1=A A A"
set "s2=B B B"
set "s3=C C C"
set "s4=D D D"
set "s5=E E E"
set "s=%s1%%dlm%%s2%%dlm%%s3%%dlm%%s4%%dlm%%s5%%dlm%"
rem set "s=%s1%%dlm%%s2%%dlm%%s3%%dlm%%s4%%dlm%%s5%" without trailing %dlm%
call :split_supplied_line "%s%" "%dlm%" "72351984test.txt"
goto :eof
:split_supplied_line
set "restofline=%~1" 1st parameter: line to split
set "delims=%~2" 2nd parameter: delimiter character
set "tofile=%~3" 3rd parameter: file where to write
:in_split_supplied_line
call set "noplusline=%restofline:%delims%=%"
if "%noplusline%"=="%restofline%" (
SETLOCAL EnableDelayedExpansion
echo !restofline!>>"%tofile%"
ENDLOCAL
goto :eof
)
for /f "tokens=1,* delims=%delims%" %%i in ("%restofline%") do (
echo %%i>>"%tofile%""
set "restofline=%%j"
)
if ""=="%restofline%" goto :eof
goto :in_split_supplied_line
Output: 2>nul del 72351984test.txt & .\SO\72351984.bat & type 72351984test.txt
A A A
B B B
C C C
D D D
E E E
However, there is a more tricky approach (unfortunately, a trailing delimiter adds a blank line into the output):
@ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
set "LF=&echo."
set "dlm=+"
set "s1=A A A"
set "s2=B B B"
set "s3=C C C"
set "s4=D D D"
set "s5=E E E"
set "s=%s1%%dlm%%s2%%dlm%%s3%%dlm%%s4%%dlm%%s5%%dlm%"
rem set "s=%s1%%dlm%%s2%%dlm%%s3%%dlm%%s4%%dlm%%s5%" without trailing %dlm%
>72351984test.txt (echo %s:+=&echo.%)
ENDLOCAL
goto :eof
Output: 2>nul del 72351984test.txt & .\SO\72351984a.bat & type 72351984test.txt
A A A
B B B
C C C
D D D
E E E