0

I have an array my_array in Bash that contains string elements formatted as such

my_array[0] = "username_1:id_1:name_1"
my_array[1] = "username_2:id_2:name_2"
my_array[2] = "username_3:id_3:name_3"

I was curious if there is a convenient way to iterate through this array splitting it on the ":" character and storing the values into three separate arrays. The pseudo-code might look something like this

index=0
for i in "${my_array}"
do
   usernames[$index], ids[$index], names[$index]= $(echo $i | tr ":" "\n")
   (( index = index + 1 ))
done

This question (How do I split a string on a delimiter in Bash?) is very similar to what I am trying to accomplish, however I am trying to store the values into three different arrays which is my main obstacle. Thanks in advance for any help as I am extremely new to bash programming.

here is what I have attempted:


index=0
for i in "${arrayAdmin[@]}"
do
        credentials=$(echo $i | tr ":" "\n" )

        accounts[$index]=${credentials[0]}
        groups[$index]=${credentials[1]}
        names[$index]=${credentials[2]}
        (( index = $index + 1))
        echo $index
done
CyberStems
  • 326
  • 2
  • 15

1 Answers1

1

Use read, then assign to each array individually.

for i in "${my_array[@]}"
do
   IFS=: read -r username id name <<< "$i"
   usernames+=("$username")
   ids+=("$id")
   names+=("$name")
done

You could write

i=0
for rec in "${my_array[@]}"
do
    IFS=: read -r usernames[i] ids[i] names[i] <<< "$rec"
    ((i++))
done

but I find the first loop more readable, in that it doesn't require an explicit loop index for the new arrays.

Or maybe using the same index variable (managed by the for loop) for both the input array and the three output arrays.

for ((i=0;i < ${#my_array[@]}; i++)); do
    IFS=: read -r usernames[i] ids[i] names[i] <<< "${my_array[i]}"
done

And finally, if you don't want to assume the array indices are a continuous sequence and you want to preserve the gaps

# For example, my_array=([0]="..." [5]="..." [10]="...")
for i in "${!my_array[@]}"; do
    IFS=: read -r usernames[i] ids[i] names[i] <<< "${my_array[i]}"
done
chepner
  • 497,756
  • 71
  • 530
  • 681
  • Thank you so much both answers worked in my case. This will sound like a rookie question but does the triple "<" just indicate that there will be three variables looking for input? – CyberStems Oct 31 '19 at 14:47
  • No, `<<<` specifies a here-string, basically a shortcut for a one-line here-document. It's unrelated to the number of variables you expect `read` to set. – chepner Oct 31 '19 at 14:51
  • @CyberStems: no, read more about here strings here: [here strings](http://www.tldp.org/LDP/abs/html/x17837.html) – lainatnavi Oct 31 '19 at 14:52