CyberStems
CyberStems

Reputation: 358

Split an array of strings into multiple other arrays within Bash

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

Upvotes: 1

Views: 1369

Answers (1)

chepner
chepner

Reputation: 531095

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

Upvotes: 2

Related Questions