Reputation: 587
I am writing bash script for first time . I have to use nested for loop
. I have an array like this:
(foo,bar a,b)
There are two elements in the array and each element in array is separated by commas. I want each element in array to split and print each element. The final result I want is
foo
bar
a
b
I am using nested for loop as below but I am not getting any response
IFS=','
echo "class names is::${classNames[@]}" // prints foo,bar a,b
for ((n=0;n<${#classNames[@]};n++)){
classes=${classNames[n]}
for ((i=0;n<${#classes[@]};i++)){
echo "${eachClass[i]}"
}
}
Upvotes: 0
Views: 937
Reputation: 10113
A practical one-liner solution without using an apparent loop is
(IFS=', '; printf '%s\n' ${classNames[*]})
It runs in a subshell not to mess up with current shell's IFS
.
Upvotes: 0
Reputation: 7253
... or like this
for item in "${arr[@]}"; {
sub=(${item//,/ })
echo "item1=${sub[0]}"
echo "item2=${sub[1]}"
}
with read
for item in "${arr[@]}"; {
read i1 i2 <<< ${item//,/ }
echo "item1=$i1"
echo "item2=$i2"
}
The trick is that we switch ',' to ' '(space) via this bash syntax ${item//,/ }
(${var_name//pattern/replacement}) this is called variable substitution. And this one <<<
is used to read directly from var.
Upvotes: 1
Reputation: 140900
You could:
arr=(foo,bar a,b)
for i in "${arr[@]}"; do
while IFS=, read -ra arr_in; do
for j in "${arr_in[@]}"; do
echo "$j"
done
done <<<"$i"
done
or like:
for i in "${arr[@]}"; do
readarray -d, -t arr_in < <(printf "%s" "$i")
for j in "${arr_in[@]}"; do
echo "$j"
done
done
or just:
while IFS=, read -ra arr_in; do
for j in "${arr_in[@]}"; do
echo "$j"
done
done < <(printf "%s\n" "${arr[@]}"
or even:
while IFS=, read -ra arr_in; do
printf "%s\n" "${arr_in[@]}"
done < <(printf "%s\n" "${arr[@]}"
but that said:
printf "%s\n" "${arr[@]}" | tr ',' '\n'
will also print the same.
Do not use {
}
as loop terminators - it's undocumented very old bash/shell syntax. Use do..done
.
classes=...
is a normal variable, not an array, and in such assignment IFS
does not matter - here the right part of =
is not word splitted. To assign an array, use braces classes=(${classNames[n]})
.
You could just split the values on spaces and comma with IFS:
IFS=', ' read -ra arr <<<"${arr[*]}"
for i in "${arr[@]}"; do
echo "$i"
done
or even like:
while IFS= read -r i; do
echo "$i"
done < <(IFS=', '; printf "%s\n" ${arr[*]})
Upvotes: 2