Skip to main content
added 86 characters in body
Source Link
Stéphane Chazelas
  • 586.9k
  • 96
  • 1.1k
  • 1.7k

Beware in bash (like in ksh whose array design bash copied), arrays are not like normal arrays but sparse arrays so more like associative arrays with keys limited to positive integers.

Here, you can do:

$ array=( [12]=a [23]=b [34]=c )
$ var=array
$ tempvar_for_separated_out_keys='!'$var[@]
$ tempvar_for_separated_out_values=$var[@]
$ printf -- '- <%s>\n' "${!tempvar_for_separated_out_keys}"
bash: !array[@]: invalid variable name
$ printf -- '- <%s>\n' "${!tempvar_for_separated_out_values}"
- <a>
- <b>
- <c>

(yes, the one for the keys doesn't work yet).

Or you could use a nameref instead (also from ksh though with some differences).

$ typeset -n var=array
$ printf -- '- <%s>\n' "${!var[@]}"
- <12>
- <23>
- <34>
$ printf -- '- <%s>\n' "${var[@]}"
- <a>
- <b>
- <c>

Or you could switch to zsh, where dereferencing is done with the P parameter expansion flag. zsh arrays are arrays, though it also has proper associative arrays with keys as arbitrary strings (of any byte or character).

$ array=( a b c '' ) var=array
$ printf -- '- <%s>\n' ${(P)var}
- <a>
- <b>
- <c>
$ printf -- '- <%s>\n' "${(P@)var}"
- <a>
- <b>
- <c>
- <>
$ typeset -A hash=( 12 a 23 b 34 c '' empty )
$ var=hash
$ printf -- '- <%s>\n' "${(Pk@)var}"
- <>
- <34>
- <23>
- <12>
$ printf -- '- <%s>\n' "${(Pv@)var}"
- <empty>
- <c>
- <b>
- <a>
$ printf -- '- <%s> -> <%s>\n' "${(Pkv@)var}"
- <> -> <empty>
- <34> -> <c>
- <23> -> <b>
- <12> -> <a>

(k flag for the keys, v flag for the values (default), @ flag inside quotes to preserve empty elements like for the Bourne shell's "$@").

Beware in bash (like in ksh whose array design bash copied), arrays are not like normal arrays but sparse arrays so more like associative arrays with keys limited to positive integers.

Here, you can do:

$ array=( [12]=a [23]=b [34]=c )
$ var=array
$ tempvar_for_separated_out_keys='!'$var[@]
$ tempvar_for_separated_out_values=$var[@]
$ printf -- '- <%s>\n' "${!tempvar_for_separated_out_keys}"
bash: !array[@]: invalid variable name
$ printf -- '- <%s>\n' "${!tempvar_for_separated_out_values}"
- <a>
- <b>
- <c>

(yes, the one for the keys doesn't work yet).

Or you could use a nameref instead (also from ksh though with some differences).

$ typeset -n var=array
$ printf -- '- <%s>\n' "${!var[@]}"
- <12>
- <23>
- <34>
$ printf -- '- <%s>\n' "${var[@]}"
- <a>
- <b>
- <c>

Or you could switch to zsh, where dereferencing is done with the P parameter expansion flag. zsh arrays are arrays, though it also has proper associative arrays with keys as arbitrary strings (of any byte or character).

$ array=( a b c '' ) var=array
$ printf -- '- <%s>\n' ${(P)var}
- <a>
- <b>
- <c>
$ printf -- '- <%s>\n' "${(P@)var}"
- <a>
- <b>
- <c>
- <>
$ typeset -A hash=( 12 a 23 b 34 c '' empty )
$ var=hash
$ printf -- '- <%s>\n' "${(Pk@)var}"
- <>
- <34>
- <23>
- <12>
$ printf -- '- <%s>\n' "${(Pv@)var}"
- <empty>
- <c>
- <b>
- <a>
$ printf -- '- <%s> -> <%s>\n' "${(Pkv@)var}"
- <> -> <empty>
- <34> -> <c>
- <23> -> <b>
- <12> -> <a>

(k flag for the keys, v flag for the values (default)).

Beware in bash (like in ksh whose array design bash copied), arrays are not like normal arrays but sparse arrays so more like associative arrays with keys limited to positive integers.

Here, you can do:

$ array=( [12]=a [23]=b [34]=c )
$ var=array
$ tempvar_for_separated_out_keys='!'$var[@]
$ tempvar_for_separated_out_values=$var[@]
$ printf -- '- <%s>\n' "${!tempvar_for_separated_out_keys}"
bash: !array[@]: invalid variable name
$ printf -- '- <%s>\n' "${!tempvar_for_separated_out_values}"
- <a>
- <b>
- <c>

(yes, the one for the keys doesn't work yet).

Or you could use a nameref instead (also from ksh though with some differences).

$ typeset -n var=array
$ printf -- '- <%s>\n' "${!var[@]}"
- <12>
- <23>
- <34>
$ printf -- '- <%s>\n' "${var[@]}"
- <a>
- <b>
- <c>

Or you could switch to zsh, where dereferencing is done with the P parameter expansion flag. zsh arrays are arrays, though it also has proper associative arrays with keys as arbitrary strings (of any byte or character).

$ array=( a b c '' ) var=array
$ printf -- '- <%s>\n' ${(P)var}
- <a>
- <b>
- <c>
$ printf -- '- <%s>\n' "${(P@)var}"
- <a>
- <b>
- <c>
- <>
$ typeset -A hash=( 12 a 23 b 34 c '' empty )
$ var=hash
$ printf -- '- <%s>\n' "${(Pk@)var}"
- <>
- <34>
- <23>
- <12>
$ printf -- '- <%s>\n' "${(Pv@)var}"
- <empty>
- <c>
- <b>
- <a>
$ printf -- '- <%s> -> <%s>\n' "${(Pkv@)var}"
- <> -> <empty>
- <34> -> <c>
- <23> -> <b>
- <12> -> <a>

(k flag for the keys, v flag for the values (default), @ flag inside quotes to preserve empty elements like for the Bourne shell's "$@").

Source Link
Stéphane Chazelas
  • 586.9k
  • 96
  • 1.1k
  • 1.7k

Beware in bash (like in ksh whose array design bash copied), arrays are not like normal arrays but sparse arrays so more like associative arrays with keys limited to positive integers.

Here, you can do:

$ array=( [12]=a [23]=b [34]=c )
$ var=array
$ tempvar_for_separated_out_keys='!'$var[@]
$ tempvar_for_separated_out_values=$var[@]
$ printf -- '- <%s>\n' "${!tempvar_for_separated_out_keys}"
bash: !array[@]: invalid variable name
$ printf -- '- <%s>\n' "${!tempvar_for_separated_out_values}"
- <a>
- <b>
- <c>

(yes, the one for the keys doesn't work yet).

Or you could use a nameref instead (also from ksh though with some differences).

$ typeset -n var=array
$ printf -- '- <%s>\n' "${!var[@]}"
- <12>
- <23>
- <34>
$ printf -- '- <%s>\n' "${var[@]}"
- <a>
- <b>
- <c>

Or you could switch to zsh, where dereferencing is done with the P parameter expansion flag. zsh arrays are arrays, though it also has proper associative arrays with keys as arbitrary strings (of any byte or character).

$ array=( a b c '' ) var=array
$ printf -- '- <%s>\n' ${(P)var}
- <a>
- <b>
- <c>
$ printf -- '- <%s>\n' "${(P@)var}"
- <a>
- <b>
- <c>
- <>
$ typeset -A hash=( 12 a 23 b 34 c '' empty )
$ var=hash
$ printf -- '- <%s>\n' "${(Pk@)var}"
- <>
- <34>
- <23>
- <12>
$ printf -- '- <%s>\n' "${(Pv@)var}"
- <empty>
- <c>
- <b>
- <a>
$ printf -- '- <%s> -> <%s>\n' "${(Pkv@)var}"
- <> -> <empty>
- <34> -> <c>
- <23> -> <b>
- <12> -> <a>

(k flag for the keys, v flag for the values (default)).