RedBelly
RedBelly

Reputation: 89

How to get each item of a comma separated string assigned to an environment variable processed within a loop?

The FOR loop only outputs the first item of the list and I'm trying to go over the whole list.

@ECHO OFF
set list=this,is,a,list
FOR /f "tokens=1* delims=," %%a IN ("%list%") DO echo %%a
pause

Upvotes: 6

Views: 14545

Answers (3)

Kendavros
Kendavros

Reputation: 1

Since Aacini's first solution can only be used with lists of known length and the second cannot be used for lists containing spaces, special characters, etc., here is a modified version of the Mofi's best approach used with a procedure call with parameters.

Cheers

@echo off&cls
:: CREATING PROCEDURE MESSAGES
set "ms1Item= List of All Items:"
set "ms2Item=  Item Number"
set "ms3Item= Number of Total Items"

:: DEFINE PROCEDURE DELIMITER
set "dlmItem=,"

:: CREATING LISTS
set "lst1=this,is,a,list,a b,c"
set "lst2=c:\@WebNet\WebSite Watcher,e:\@WebNet Tools\Bandwidth Monitor\"
set "lst3=this-is-an-other-list-aaaa, bbbb-with spaces-and comma"

:: PROCEDURE CALLS
call:getItem "%lst1%" "echo.              Item Value is:" x x x x
echo.&pause&cls
call:getItem "%lst2%" "echo.  Item Value is"  x x x x
echo.&pause&cls
call:getItem "%lst2%" "dir /o:en" "echo.&pause&cls" x
echo.
call:getItem "%lst2%" "dir /b /o:en" "echo.&timeout /t 10>nul" "" "" x
cls

:: REDEFINE PROCEDURE DELIMITER
set "dlmItem=-"
call:getItem "%lst3%" "echo.              Item Value is:" x x x x

echo.&pause&goto:eof
:: END OF PROCEDURE CALLS

:getItem
:: PROCEDURE PARAMETERS
:: %1 COMPLETE ITEMS SEPARATED BY %dlmItem%
:: %2 A COMMAND TO BE EXECUTED WITH THE ITEM
:: %3 A COMMAND TO BE EXECUTED AFTER OR X
:: %4 IF SET DISPLAY THE LIST OF ALL ITEMS
:: %5 IF SET DISPLAY THE ITEMS COUNT
:: %6 IF SET DISPLAY THE ITEMS TOTAL
if "%~3" EQU "" echo.&goto:getItemEND
set /A cntItem=0
set "newItem=%~1"
set "cmdItem=%~2"
set "nxtItem=%~3"
if "%~4" NEQ "" echo.%ms1Item% %newItem%&echo.
:oneItem
  if "%newItem%" EQU "" goto:oneItemEND
  set /A cntItem+=1
  for /F "tokens=1* delims=%dlmItem%" %%a in ("%newItem%") do (
    set "oneItem=%%a"
    set "newItem=%%b"
  )
  if "%~5" NEQ "" echo.%ms2Item% %cntItem%
  %cmdItem% "%oneItem%"
  if /I "%nxtItem%" NEQ "x" %nxtItem%
  goto oneItem
:oneItemEND
if "%~6" NEQ "" echo.&echo.%ms3Item% %cntItem%
:getItemEND
exit/b
:: END OF PROCEDURE

NB: echo.bell string ALT007 and change set "lst2=..." with your values

Upvotes: 0

Aacini
Aacini

Reputation: 67216

The FOR /F command split a line in several tokens, that must be referenced individually via separate letters:

@ECHO OFF
set list=this,is,a,list
FOR /f "tokens=1-4 delims=," %%a IN ("%list%") DO (
   echo %%a
   echo %%b
   echo %%c
   echo %%d
)
pause

The plain FOR command process a series of elements separated by space, or by the standard Batch file delimiters: comma, semicolon or equal-sign:

@ECHO OFF
set list=this,is,a,list
FOR %%a IN (%list%) DO echo %%a
pause

Upvotes: 12

Mofi
Mofi

Reputation: 49096

Open a command prompt window, run for /? and read the output help.

With tokens=1* the first string delimited by 1 or more commas (,,, is like 1 comma!) is assigned to loop variable a which is here the word this. And the rest of the string being is,a,list is assigned to loop variable b (next after a in ASCII table) which is not referenced at all in provided code snippet.

Here is a batch code demonstrating how to process each substring of a comma separated string:

@echo off
set "List=this,is,a,list"
set ItemCount=0

:NextItem
if "%List%" == "" pause & goto :EOF

set /A ItemCount+=1
for /F "tokens=1* delims=," %%a in ("%List%") do (
    echo Item %ItemCount% is: %%a
    set "List=%%b"
)
goto NextItem

The output is:

Item 1 is: this
Item 2 is: is
Item 3 is: a
Item 4 is: list

There are of course also other solutions possible. This is just an example.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • echo /?
  • for /?
  • goto /?
  • if /?
  • pause /?
  • set /?

Upvotes: 3

Related Questions