I did not set the value of the string using a FOR loop did I. Nor did the OP specify how the variable is to be initially set. The
comma collapsing code I posted absolutely works in all cases.
I do not consider how the string is initially set to be part of the original question.
FACT - given any string stored in an environment variable, the algorithms I've posted properly handle the collapsing of the commas. How the string is initially set is NOT part of the algorithm.
I'm not saying that setting the initial value is trivial in all cases. I already stated in an earlier post:
dbenham wrote:The initial population of the string variable could be an issue, but for me, that is outside the scope of the problem. And there are multiple methods to solve that any way.
The same cannot be said for any algorithm that relies on normal expansion without the use of delayed expansion. I do not believe it is possible to properly collapse commas for all possible string values unless delayed expansion is used.
To address your last situation that "doesn't work" - The solution is simple. And it does not change how the commas are collapsed.
Code: Select all
@echo off
> file.txt echo ,,,!value1!,value2 opt,,,value3,,value4 opt,,,value5,,,,,
setlocal disableDelayedExpansion
for /f "delims=" %%a in (file.txt) do (
set str=%%a
setlocal enableDelayedExpansion
REM Bullet-proof comma collapsing begins here!
if defined str (
for /l %%N in (1 1 13) do set "str=!str:,,=,!"
if "!str:~0,1!"=="," set "str=!str:~1!"
if defined str if "!str:~-1!"=="," set "str=!str:~0,-1!"
)
REM comma collapsing ends here!
echo !str!
endlocal
)
pause
How would you do the above without delayed expansion? Not only would it not properly handle all possible values, but you would have to use at least one CALL statement. And CALL is SLOW. If the file is large then the delayed expansion solution will be MUCH faster.
There is also a solution if you need to disable delayed expansion when finished and preserve the value across the endlocal barrier. Yet again, the comma collapsing algorithm does not change.
Code: Select all
@echo off
> file.txt echo ,,,!value1!,value2 opt,,,value3,,value4 opt,,,value5,,,,,
setlocal disableDelayedExpansion
for /f "delims=" %%a in (file.txt) do (
set str=%%a
setlocal enableDelayedExpansion
REM Bullet proof comma collapsing begins here!
if defined str (
for /l %%N in (1 1 13) do set "str=!str:,,=,!"
if "!str:~0,1!"=="," set "str=!str:~1!"
if defined str if "!str:~-1!"=="," set "str=!str:~0,-1!"
)
REM comma collapsing ends here!
echo !str!
for /f "eol=, delims=" %%b in ("!str!") do (
endlocal
set "str=%%b"
)
)
echo %str%
pause
It is even possible to encapsulate the algorithm in a subroutine that can accept any string variable with absolutely any value, collapse the commas, and return the correct value across the endlocal barrier without worrying about whether the routine was called with delayed expansion enabled or disabled. Or for ultimate performance, the algorithm could be encapsulated in a macro that does the same. But that is way beyond the scope of the original question. The techniques to do this are the same regardless what algorithm you are trying to encapsulate, and the techniques have been extensively documented in other posts.
Dave Benham