Your issue are with the spaces in the data. The shell will split the string into words on all spaces and the for loop will iterate over those words.
(For a solution that does not replace variable_list with an array, see the very end of this answer.)
Instead, use a proper array:
variable_list=(
"any:any:-a -b -c any"
"one:one:-c -b -f -m mul"
"mul:one:-c -b -f -m mul"
)
for var in "${variable_list[@]}"; do
c1=$( cut -d':' -f1 <<<"$var" )
c2=$( cut -d':' -f2 <<<"$var" )
c3=$( cut -d':' -f3- <<<"$var" )
printf 'c1==>%s and c2==>%s and c3==>%s\n' "$c1" "$c2" "$c3"
done
Using an array ensures that you can access each individual set of variables as its own array entry without relying on them being delimited by newlines or some other character.
The code is also using "here-strings" in bash to send the string to cut (rather than echo and a pipe).
Or, much more efficiently,
variable_list=(
"any:any:-a -b -c any"
"one:one:-c -b -f -m mul"
"mul:one:-c -b -f -m mul"
)
for var in "${variable_list[@]}"; do
IFS=':' read -r c1 c2 c3 <<<"$var"
printf 'c1==>%s and c2==>%s and c3==>%s\n' "$c1" "$c2" "$c3"
done
Setting IFS to a colon for read will make read split the input on colons (rather than on spaces, tabs and newlines).
Note that all the quotation above is significant. Without the double quotes, the shell would perform word splitting and filename globbing on the values of variable_list, var and the three c variables.
Related:
If all you're after is that specific output, then you may cheat a bit:
variable_list=(
"any:any:-a -b -c any"
"one:one:-c -b -f -m mul"
"mul:one:-c -b -f -m mul"
)
( IFS=':'; set -f; printf 'c1==>%s and c2==>%s and c3==>%s\n' ${variable_list[@]} )
This runs the printf in a subshell so that setting IFS and the -f (noglob) shell option does not affect the rest of the script. Setting IFS to a colon here will make the shell expand the unquoted variable_list array into three sets of three arguments for printf. printf will print the first three according to its format string and then reuse that format for the next set of three arguments, until all arguments have been processed.
The set -f prevents the unquoted expansion of variable_list from triggering filename globbing, should there be any filename globbing characters in there.
Using a newline-delimited string:
variable_list="
any:any:-a -b -c any
one:one:-c -b -f -m mul
mul:one:-c -b -f -m mul"
while IFS= read -r var; do
IFS=':' read -r c1 c2 c3 <<<"$var"
printf 'c1==>%s and c2==>%s and c3==>%s\n' "$c1" "$c2" "$c3"
done <<<"$variable_list"
This reads the data from the string as if it came from a file.
Related:
cut -d: -f3 < inputworks; as doescut -d: -f3- < input– Jeff Schaller Jul 12 '18 at 14:15