I have a delimited list of IPs I'd like to process individually. The list length is unknown ahead of time. How do I split and process each item in the list?
@echo off
set servers=127.0.0.1,192.168.0.1,10.100.0.1
FOR /f "tokens=* delims=," %%a IN ("%servers%") DO call :sub %%a
:sub
echo In subroutine
echo %1
exit /b
Outputs:
In subroutine
127.0.0.1
In subroutine
ECHO is off.
Update: Using Franci's answer as reference, here's the solution:
@echo off
set servers=127.0.0.1,192.168.0.1,10.100.0.1
call :parse "%servers%"
goto :end
:parse
setlocal
set list=%1
set list=%list:"=%
FOR /f "tokens=1* delims=," %%a IN ("%list%") DO (
if not "%%a" == "" call :sub %%a
if not "%%b" == "" call :parse "%%b"
)
endlocal
exit /b
:sub
setlocal
echo In subroutine
echo %1
endlocal
exit /b
:end
Outputs:
In subroutine
127.0.0.1
In subroutine
192.168.0.1
In subroutine
10.100.0.1
If PowerShell is available you could:
Another use to display a readable PATH variable.
or
The for command handles a number of delimiters by default. In this case you can do
If you run into a delimiter that is not natively supported, you could do a replace to first prepare the string so it is in the right format
Using recursive calls has the chance to run out of stack space once you go over a certain number of items in the list. Also testing it, the recursion pattern seems to run a bit slower.
The difficulty is that the for command is intended to work on multiline text strings that you would typically find in files. The best solution I've found to this problem is to modify your string to be multiline.
This final for loop will iterate over the items in the space separated variable. It does it by replacing the space in the list variable with newlines, then doing the normal for loop.
I can't believe this is so complicated! Seems like everyone would want to split a string frequently without knowing how many tokens are in it and without parsing it by lines. Typically, it seems people are writing to a file and then step through it or using a multi sub method like these others. What a mess!
Here's my solution. It's easier to follow and works inline, i.e. no sub routine. It is nice to build a list of filenames or whatever and then step through them without having to write to them to a temp file, ensure there is no file writing collision, delete the temp file etc. Plus I don't know how to return a value from a sub like it was a function - I don't think you can. So you'd have to keep writing 2 subs with the other answers I see here each time you wanted to do something like this - one that feeds the other. My method lets you easily create lists and step through them as many times as you want throughout the script.
Output:
Obviously you can just exchange the echo with something useful.
This is a generalisation of Franci's solution, so that you can perform any job on each item in your list, without having copies of the list iteration code.
Eg, you can call it by:
Yes, I know this is a very old topic, but I recently discovered and interesting trick that can perform the requested split in a much simpler way. Here it is:
These two lines split the
servers
string into theserver
array and also definen
variable with the number of created elements. This way, you just need to use afor /L
command from 1 to%n%
to process all elements. Here it is the complete code:This method is not just simpler and faster than any other method based on
for
command, but it also allows to directly use a multi-character string as delimiter.You may read further details on the splitting method at this post.