Home > OS >  Put every other value into a seperate array
Put every other value into a seperate array

Time:12-20

I have a basic array at the moment and it works as expected. But what I want to do is put every other value into a seperate array. I just need the 100 and 200 to be in array 1, and 1000 and 2000 to be in array 2. How do I do that?

$ cat scriptx.sh 
while read line
do
    my_array=("${my_array[@]}" $line)
done

echo ${my_array[@]}
$ ./scriptx.sh 
100
1000
200
2000
100 1000 200 2000

CodePudding user response:

For an arbitrary number of arrays n_arrays, you can use a counter of lines read so far, dynamically generate array names, such as array_0, array_1 etc., and append new lines to the right arrays based on counter % n_arrays. Obviously, n_arrays set to 2 gives an answer to the question.

#!/bin/bash
set -euo pipefail

declare -ri n_arrays=2          # number of arrays to use
declare -i i counter=0          # number of lines read so far
for ((i = 0; i < n_arrays;   i)); do
  declare -a "array_${i}"       # optional; needed with set -u
done

while IFS= read -r line; do
  declare -n my_array="array_$((counter   % n_arrays))"
  my_array =("$line")           # append line to the right array
done

for ((i = 0; i < n_arrays;   i)); do
  declare -n my_array="array_${i}"
  echo "${my_array[@]@A}"       # print a declare assign command
done

CodePudding user response:

Something along the lines of:

#!/bin/bash

while IFS= read -r line; do
    array1 =("$line")
    if IFS= read -r line; then
        array2 =("$line")
    fi
done
    
echo "array1: ${array1[*]}"
echo "array2: ${array2[*]}"

CodePudding user response:

You could do something like this:

#!/bin/bash

i=0
while read line; do
    if (( i   % 2 )); then
        odd_indexes =($line)
    else
        even_indexes =($line)
    fi
done

echo "even_indexes: ${even_indexes[*]}"
echo "odd_indexes: ${odd_indexes[*]}"

Assuming that your input data is:

100
1000
200
2000

This script will output:

even_indexes: 100 200
odd_indexes: 1000 2000

But you could also do something like this if you don't mind reading the input file twice:

#!/bin/bash

mapfile -t odd_indexes < <(sed -n 'n;p' data.txt)
mapfile -t even_indexes < <(sed -n 'p;n' data.txt)

echo "even_indexes: ${even_indexes[*]}"
echo "odd_indexes: ${odd_indexes[*]}"

If you're reading from stdin you would need to write that out to a temporary file and use that file in the above script.

CodePudding user response:

One idea:

$ cat runme
#!/bin/bash

cnt=${1:-2}                                   # 1st (optional) arg states number of arrays; if not supplied default is '2'

for ((i=1;i<=cnt;i  ))
do
    unset array_"$i"                          # make sure arrays do not exist
done

n=0

while read -r line
do
    (( ndx = n  %cnt  1 ))                    # calculate array index
    declare -n curr_array=array_"${ndx}"      # use nameref to dynamically reference correct array
    curr_array =( "${line}" )                 # add line to array
done

echo ""
for ((i=1;i<=cnt;i  ))                        # display contents of our arrays
do
    typeset -p array_"$i"
done

Taking for a test drive:

$ runme
100
1000
200
2000

declare -a array_1=([0]="100" [1]="200")
declare -a array_2=([0]="1000" [1]="2000")

$ runme 2
100
1000
200
2000

declare -a array_1=([0]="100" [1]="200")
declare -a array_2=([0]="1000" [1]="2000")

$ runme 3
1 a
2 b
3 c
4 d
5 e

declare -a array_1=([0]="1 a" [1]="4 d")
declare -a array_2=([0]="2 b" [1]="5 e")
declare -a array_3=([0]="3 c")
  • Related