How to iterate through a comma-separated list and execute a command for each entry
Splitting a string at a particular character is built into the shell at a very deep level: if you write $var
without any surrounding quotes, then it is expanded as follows:
- Take the value of the
var
variable. - Split this value into a list of fields. The field separator is any character in the value of the
IFS
variable. IfIFS
contains whitespace characters, then consecutive separators are considered as one; for non-whitespace characters, consecutive separators result in empty fields. - Perform globbing, i.e. interpret each resulting field as a file name wildcard pattern. For each pattern that matches one or more files, replace it by the list of matching files.
The same happens for a command substitution $(somecommand)
, except that step 1 is “collect the output from running somecommand
and strip all newlines at the end”.
To avoid all this rigmarole and just get the exact value of the variable, or the output of the command minus final newlines, be sure to put the variable substitution or command substitution between double quotes: "$foo"
, "$(foo)"
.
To split the result of a command susbtitution at comma characters, set IFS=,
and leave the substitution unprotected. You need to do one more thing: turn off globbing, with set -f
(and restore it afterwards with set +f
.
all_jobs=$(…)
set -f; IFS=,
for job in $all_jobs; do
sendevent -verbose -S NYT -E JOB_OFF_HOLD -J "$job" --owner me
done
set =f; unset IFS
If you're sure that the fields between the commas do not contain any whitespaces than you could do something like this:
for job in $(echo $all_jobs | tr "," " "); do
sendevent -verbose -S NYT -E JOB_OFF_HOLD -J "$job" --owner me
done
If you need something more robust, take a look at the tools needed to deal with CSV files under Unix.