Home > Net >  bash: get size and [x,y]-element from a list of different size arrays
bash: get size and [x,y]-element from a list of different size arrays

Time:07-23

BASH: I have a list of array of different size from an external config sourced file:

declare -a line0=( 00 01 02    )
declare -a line1=( 10 11       )
...
declare -a line9=( 90 91 92 93 )
rows=9

Getting the size of a single array works as so:

${#line0[@]}

this can be practical only for few arrays like in the example.

I need to get the array size in a for loop. I tryed this:

for ((r=0;r<rows;r  )) do
   line="line$r"
   echo line:$line
   cols="${#$line[@]}"    # 1st assignment
   cols="${#line$r[@]}"   # 2nd assignment
done

but got 'bad substitution' error for both assignment.

Then, supposing to know the max cols value, I need to extract the single element from arrays with two nested loops. I tryed so:

cols=4
for ((r=0;r<rows;r  )) do
   line="line$r"
   echo line:$line
   for ((c=0;c<cols;c  )) do
      val=${$line[$c]}    # 1st assignment
      val=${line$r[$c]}   # 2nd assignment
      echo val:$val
   done
done

but got 'bad substitution' error for both assignment.

Edit: what is the right method to get size and [x,y]-element from a list of different size arrays?

I looked for other questions, but there are solutions for same sized arrays only

CodePudding user response:

You can make use of indirect reference with declare -n ref=varname. Would you please try:

for ((r = 0; r < rows; r  )); do
    declare -n line="line$r"        # now "line" will be a reference to the array
    cols="${#line[@]}"              # you can access the array with the name "line"
    echo "line:$r cols:$cols"
done

BTW it might be better to say rows=10, because the count of rows is 10 (IMHO).

CodePudding user response:

like so is perfect:

declare -a line0=( 00 01 02    )
declare -a line1=( 10 11       )
...
declare -a line9=( 90 91 92 93 )
rows=10
for ((r=0;r<rows;r  )) do
   declare -n line="line$r"
   #echo line:"$line"
   cols="${#line[@]}"
   echo cols:$cols
   for ((c=0;c<cols;c  )) do
      val=${line[$c]}
      echo r:$r c:$c val:$val
   done
done

The only strange think is that printing "line" return something non-sense:

echo line:"$line"

show (seems 1st element of lineN):

line:00
line:10
...

but I do not need to print that, only to use as refs, works, thanks

CodePudding user response:

Another method could be

#!/bin/bash

source configfile

for arrname in ${!line*}; do
    [[ $arrname =~ ^line[0-9] $ ]] || continue
    declare -n arrptr=$arrname
    printf 'line:%d size:%d\n' "${arrname#line}" "${#arrptr[@]}"
done

This assumes all arrays whose names match the regular expression ^line[0-9] $ are of interest.

  •  Tags:  
  • bash
  • Related