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.