You can't loop like you are showing because your input is a single line, and read
reads a line at a time. The read
operation reads the first and all subsequent fields into the single variable you provide.
If you want to process your input string item by item, you can do so by converting the items into the elements of an array and then iterating over these:
readarray -d , -t csvArray < <( printf '%s' "$csvString" )
for item in "${csvArray[@]}"; do
printf '%s\n' "$item"
done
I'm using printf
with readarray
above to avoid adding a newline character at the end of the string (<<<"$csvString"
would add a newline).
However, if your input string is a CSV string and not a simple list of comma-delimited substrings, then you can't rely on readarray
to split your string correctly since some fields may contain embedded delimiters. You would instead use a CSV-aware tool, such as Miller (mlr
), to parse the string and to perform whatever action it is that you want to do.
$ csvString='"1, 2, 3",Hello world,A,B,C'
$ mlr --csv -N put -q 'for (k,v in $*) { emit v }' <<<"$csvString"
"1, 2, 3"
Hello world
A
B
C
The above mlr
command iterates over the single header-less CSV input record, outputting the value in each field as a new record. Miller quotes the first emitted record automatically since it contains embedded commas.
csvString
to$csvString
– Edgar Magallon Jan 27 '23 at 04:37string1,string2,string3
and you sewhile IFS=, read item item2; do ...
the values ofitem
anditem2
will bestring1
andstring2,string3
respectively – Edgar Magallon Jan 27 '23 at 05:25item1 item2
. But the length of parameters is not known beforehand. I don't know how manyitemX
there is in the string. – Saeed Neamati Jan 27 '23 at 05:43bash
use:readarray -d ',' -t vals <<< "$csvString"
. That will create an array with aN
number of items (according to the delimiter:,
). You will be able to loop over the array – Edgar Magallon Jan 27 '23 at 05:47