#!/bin/bash # arrayPopulate - bash function to populate array variable from arguments, # with ability to group any numbers of element by index (row).. # Inspired by https://lists.gnu.org/archive/html/bug-bash/2025-07/msg00168.html # (C) 2025 Felix Hauri - felix@f-hauri.ch # shellcheck disable=SC2059 # This use printf to map array into format strings # Doing some cosmetic if script is executed (not sourced). if [[ $0 = "${BASH_SOURCE[0]}" ]]; then exec 4>&1 exec 3> >(sed -ue 's/^[^ U/]/$ &/;s/^/ /;/[Ee]xit/{$!N;$!N;d}'| sed -ue '/() {/,/^ $ }/{ /() {/! s/$ //}') exec 2>&3; exec 1>&3 trap 'exec 1>&4; exec 2>&4; exec 3>&-; wait; exit 0' 0 1 2 3 6 15 set -v fi arrayPopulate() { local -i __origin=0 __lines __FieldByRow=1 local OPTIND OPTARG __opt __tFmt __nl=$'\1' while getopts 'f:O:n:' __opt; do case $__opt in f ) __FieldByRow=$OPTARG ;; O ) __origin=$OPTARG ;; n ) __lines=$OPTARG ;; * ) local __oid=$((OPTIND-1)) __tFmt='Unknown arg: "%s"!\n' __tFmt+='Usage: %s [-O origin] [-n number] [-f field by row]\n' printf "$__tFmt" "${!__oid}" "${FUNCNAME[0]}" >&2 return 1;; esac; done shift "$((OPTIND - 1))" local -n __target=$1 shift printf -v __tFmt '%*s' $__FieldByRow __tFmt=${__tFmt// /%s"${IFS::1}"} __tFmt=${__tFmt%"${IFS::1}"} local IFS="$__nl" printf -v __tFmt "${__tFmt% }$__nl" "$@" mapfile -d "$__nl" -O ${__origin} ${__lines+-n} $__lines -t \ __target <<<"${__tFmt%"$__nl"}" __tFmt="${__tFmt//[!"$__nl"]}" [[ $__lines ]] && [[ $__lines -lt ${#__tFmt} ]] && return printf -v "__target[${#__tFmt}+__origin-1]" %s \ "${__target[${#__tFmt}+__origin-1]%$'\n'}" } # Exit here if script is sourced [[ $0 = "${BASH_SOURCE[0]}" ]] || { true; return 0;} dumpArray() { local _fmt_str; local -n _array=$1 printf -v _fmt_str ' [%q]=%%s\n' "${!_array[@]}" printf "$_fmt_str" "${_array[@]@Q}" } printf -v tmpStr '%s %s %s\n' {a..c}{0..2} mapfile -t T <<<"${tmpStr%$'\n'}" dumpArray T printf -v tmpStr '%s %s %s\n' {d..f}{0..2} mapfile -O 1 -t T <<<"${tmpStr%$'\n'}" dumpArray T printf -v tmpStr '%s %s %s\n' {g..i}{0..2} mapfile -O 2 -n 1 -t T <<<"${tmpStr%$'\n'}" dumpArray T printf -v tmpStr '%s %s %s\n' {a..b}{0..2} mapfile -O $((${#T[@]}-1)) -t T <<<"${tmpStr%$'\n'}" dumpArray T unset T : Strictly as your initial post arrayPopulate -f 3 T {a..c}{0..2} dumpArray T arrayPopulate -f 3 -O 1 T {d..f}{0..2} dumpArray T arrayPopulate -f3 -O2 -n1 T {g..i}{0..2} dumpArray T arrayPopulate -f3 -O$((${#T[@]}-1)) T {a..b}{0..2} dumpArray T : With fields containing spaces or newlines arrayPopulate -f 3 -O 1 T Hello\ {people,world,universe}! dumpArray T arrayPopulate -f 3 -O 3 T $'Hello,\n '{people,world,universe}! dumpArray T : There are no help, but arrayPopulate -h : Then with another row separator than a space IFS=, arrayPopulate -f 4 U {942..142..-200}{y..A..-8} dumpArray U IFS=';' arrayPopulate -f2 V $'Hello,\n '{dear,people,world,universe}! dumpArray V