bash - How to allocate array which is passed to a function by name -
i want create function iterates through array , inserts given value, if not yet included. using function on 2 different parts of code , have use different arrays. therefore delivering array names function. can't figure out how allocate slot of array store element @ place.
here code:
name=("hello" "world") function f { array_name=$2[@] array=("${!array_name}") length=${#array_name[@]} (( = 0; <= $length; i++ )); if [[ "${array[i]}" = "$1" ]]; break; fi if [[ "$i" = "$length" ]]; ${2[$length+1]=$1}; fi done } f "test" "name"
edit: want array append given value this
for in ${name[@]} echo $i done
would have output:
hello world test
but apparently "${2[$length+1]=$1}"
not working.
(idea passing array here: bash how pass array argument function)
if understand correctly want append value array if value not yet in array, tricky part array name passed function.
method 1
one possibility see problem different viewpoint: can pass function value inserted , full array, , function set global variable recover after execution. our test example we'll use:
array=( hello world "how today?" )
and we'll try insert test
, hello
(so hello
not inserted):
f() { # function set global variable _f_out array obtained # positional parameters starting position 2, $1 appended if , # if $1 doesn't appear in subsequent positional parameters local v=$1 shift _f_out=( "$@" ) i; [[ $i = $v ]] && return; done _f_out+=( "$v" ) }
let's use it:
$ array=( hello world "how today?" ) $ f test "${array[@]}" $ array=( "${_f_out[@]}" ) $ printf '%s\n' "${array[@]}" hello world how today? test $ f hello "${array[@]}" $ array=( "${_f_out[@]}" ) $ printf '%s\n' "${array[@]}" hello world how today? test
it works.
remark. used for i; do
. it's nice shortcut for in "$@"; do
.
method 2
you want fiddle simili-pointers , appending in place (this not in spirit of bash—that's why it's bit clumsy). tool use printf
-v
option: help printf
:
-v var assign output shell variable var rather display on standard output
the thing works array fields.
warning: might see other methods use eval
. avoid them plague!
f() { local array_name=$2[@] local array=( "${!array_name}" ) in "${array[@]}"; [[ $i = $1 ]] && return; done # $1 not found in array, let's append printf -v "$2[${#array[@]}]" '%s' "$1" }
and let's try it:
$ array=( hello world "how today?" ) $ f test array $ printf '%s\n' "${array[@]}" hello world how today? test $ f hello array $ printf '%s\n' "${array[@]}" hello world how today? test
it works too.
note. both methods can have return
code of function, e.g., 0
(success) if value inserted, , 1
(failure) if value there (or other way round)—the adaptation straightforward , left exercise. might useful in method 1 determine whether need update array
returned value _f_out
or not. in case, modify f
doesn't set _f_out
when value in array.
caveat. in both methods shown assumed arrays have contiguous indices start @ 0 (i.e., non-sparse arrays). think it's safe assumption here; if not case, these methods broken: first 1 (after reassignment) transform array non-sparse one, , second 1 might overwrite fields (as, array a
, ${#a[@]}
expands number of elements in array, not highest index + 1 found in array).
Comments
Post a Comment