在bash中,我有一個包含值的陣列:
declare -A my_array
my_array['key1']='value1'
my_array['key2']='value2'
echo "-----my_array-----"
echo key1: ${my_array['key1']}
echo key2: ${my_array['key2']}
什么效果很好:
-----my_array-----
key1: value1
key2: value2
雖然,我想要一個鍵,一個值串列。我試過類似的東西:
my_array['key2']=('value2.1', 'value2.2')
這給出了錯誤:
my_array ['key2']:無法將串列分配給陣列成員
將串列添加到陣列元素中然后訪問鍵的索引值的語法是什么?
uj5u.com熱心網友回復:
不。從技術上講,shell 變數僅用于保存字串。但...
在下面創建陣列陣列(甚至是associative)重擊
我將使用磁盤空閑:df -k輸出來創建關聯陣列,由設備索引。由于tmpfs偽設備用于許多不同的行為,因此該欄位 必須包含一個list。
最簡單的方法,使用特殊的分隔符。
在這里,我spaces用來分隔欄位的內容,因為它們是由命令分隔的空格。然后我使用bell特殊字符 ( \007) 來分隔子陣列。
這是一個示例,使用df輸出,按設備排序創建串列。結果,所有內容都tmpfs將存盤在一起:
declare -A dfVars
{
read _;
while read -r dev _ use free _ mpnt ;do
dfVars["${dev##*/}"] ="$use $((use free)) $mpnt"$'\07'
done
} < <(
LANG=C df -lk
)
你可以決議:
for dev in ${!dfVars[@]} ;do
IFS=$'\a\n' read -d '' -ra fields <<<"${dfVars["$dev"]%$'\a'}"
for line in "${fields[@]}";do
read -r use tot mpnt <<<"$line"
printf "%-20s d d %s\n" $dev $use $tot $mpnt
done
done
可能會輸出如下內容:
tmpfs 0 188928 /dev/shm
tmpfs 19284 188928 /run
tmpfs 4 5120 /run/lock
tmpfs 0 188928 /sys/fs/cgroup
tmpfs 0 37784 /run/user/33
tmpfs 0 37784 /run/user/1001
devtmpfs 0 184596 /dev
mmcblk0p1 23193 42136 /boot
root 115253500 117652696 /
一切都存盤在$dfVars:
declare -p dfVars
declare -A dfVars=([tmpfs]=$'0 188928 /dev/shm\a19284 188928 /run\a4 5120 /run/l
ock\a0 188928 /sys/fs/cgroup\a0 37784 /run/user/33\a0 37784 /run/user/1001\a' [d
evtmpfs]=$'0 184596 /dev\a' [mmcblk0p1]=$'23193 42136 /boot\a' [root]=$'11529034
8 117652696 /\a' )
更強:nameref 用于索引陣列:
使用這種方法,您可以創建獨立變數,可以是陣列、關聯陣列甚至是字串...
uuvar() { printf -v "$1" %s d "$2" $(( uuVarCnt));}
declare -A dfVars
{
read _
while read -r dev _ use free _ mpnt ;do
uuvar vname _df_
dfVars["${dev##*/}"] =$vname' '
read -a $vname <<<"$use $((use free)) $mpnt"
done
} < <(LANG=C df -lk)
要決議這個:
for dev in ${!dfVars[@]} ;do
for sub in ${dfVars["$dev"]};do
declare -n subDf=$sub
printf "%-20s d d %s\n" "$dev" "${subDf[@]}"
done
done
tmpfs 0 188928 /dev/shm
tmpfs 19284 188928 /run
tmpfs 4 5120 /run/lock
tmpfs 0 188928 /sys/fs/cgroup
tmpfs 0 37784 /run/user/33
tmpfs 0 37784 /run/user/1001
devtmpfs 0 184596 /dev
mmcblk0p1 23193 42136 /boot
root 115254628 117652696 /
where$dfVars和sub 變數如下所示:
declare -p dfVars uuVarCnt;set | grep ^_df_
declare -A dfVars=([tmpfs]="_df_000000003 _df_000000004 _df_000000005 _df_000000
006 _df_000000008 _df_000000009 " [devtmpfs]="_df_000000002 " [mmcblk0p1]="_df_0
00000007 " [root]="_df_000000001 " )
declare -- uuVarCnt="9"
_df_000000001=([0]="115335328" [1]="117652696" [2]="/")
_df_000000002=([0]="0" [1]="184596" [2]="/dev")
_df_000000003=([0]="0" [1]="188928" [2]="/dev/shm")
_df_000000004=([0]="19284" [1]="188928" [2]="/run")
_df_000000005=([0]="4" [1]="5120" [2]="/run/lock")
_df_000000006=([0]="0" [1]="188928" [2]="/sys/fs/cgroup")
_df_000000007=([0]="23193" [1]="42136" [2]="/boot")
_df_000000008=([0]="0" [1]="37784" [2]="/run/user/33")
_df_000000009=([0]="0" [1]="37784" [2]="/run/user/1001")
相同,但使用關聯陣列:
declare -A dfVars
uuvar() { printf -v "$1" %s d "$2" $(( uuVarCnt));}
{
read _
while read -r dev _ use free _ mpnt ;do
uuvar vname _df_
dfVars["${dev##*/}"] =$vname' '
declare -A $vname
printf -v $vname[used] %d $use
printf -v $vname[total] %d $((use free))
printf -v $vname[mount\ point] %s "$mpnt"
done
} < <(LANG=C df -lk)
for dev in ${!dfVars[@]} ;do
for sub in ${dfVars["$dev"]} ;do
declare -n subDf=$sub
printf "%-20s d d %s\n" "$dev" \
"${subDf[used]}" "${subDf[total]}" "${subDf["mount point"]}"
done
done
## < snip same output >
然后
declare -p dfVars uuVarCnt;set | grep ^_df_
declare -A dfVars=([tmpfs]="_df_000000003 _df_000000004 _df_000000005 _df_000000
006 _df_000000008 _df_000000009 " [devtmpfs]="_df_000000002 " [mmcblk0p1]="_df_0
00000007 " [root]="_df_000000001 " )
declare -- uuVarCnt="9"
_df_000000001=([used]="115358360" [total]="117652696" ["mount point"]="/" )
_df_000000002=([used]="0" [total]="184596" ["mount point"]="/dev" )
_df_000000003=([used]="0" [total]="188928" ["mount point"]="/dev/shm" )
_df_000000004=([used]="19284" [total]="188928" ["mount point"]="/run" )
_df_000000005=([used]="4" [total]="5120" ["mount point"]="/run/lock" )
_df_000000006=([used]="0" [total]="188928" ["mount point"]="/sys/fs/cgroup" )
_df_000000007=([used]="23193" [total]="42136" ["mount point"]="/boot" )
_df_000000008=([used]="0" [total]="37784" ["mount point"]="/run/user/33" )
_df_000000009=([used]="0" [total]="37784" ["mount point"]="/run/user/1001" )
uj5u.com熱心網友回復:
這是不可能的,但有一種方法可以通過變數擴展來做到這一點,如下所示:
declare -A my_array
my_array['key1']='value1'
my_array['key2']='value2'
value1="true value1"
value2="true value2"
查看:
$ echo ${!my_array['key1']}
true value1
$ echo ${!my_array['key2']}
true value2
如果 value* 是一個陣列,那就更復雜了,但也有可能:
...
value1=("true value1.1" "true value1.2")
value1=("true value2.1" "true value2.2")
index="${my_array['key1']}[0]"
$ echo "${!index}"
true value2.1
這可以包裝在一個函式中:
fun(){
local index1=${!1}
local index2="$index1[$2]"
echo "${!index2}"
}
$ fun "my_array['key2']" 1
true value2.2
但是 IMO 您應該接受限制并重新考慮設計或考慮使用另一種語言。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/432096.html
上一篇:將字典ByRef傳遞給excelVBA用戶表單模塊中的私有子會給出ByRef型別不匹配錯誤
下一篇:使用地圖按特定順序插入物件
