gpt4 book ai didi

arrays - Bash - 如何将列表分配给数组成员

转载 作者:行者123 更新时间:2023-12-05 05:45:59 25 4
gpt4 key购买 nike

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']: cannot assign list to array member

将列表添加到数组元素然后访问键的索引值的语法是什么?

最佳答案

没有。从技术上讲,shell 变量 仅用于保存字符串。但是……

下创建数组的数组(甚至关联)

我将使用disk free:df -k 输出来创建关联数组,由设备 索引。作为 tmpfs 伪设备用于许多不同的行为,这个字段必须包含一个列表

最简单的方法,使用特殊分隔符。

这里我使用 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 %11d %11d %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%09d "$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 %11d %11d %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 /

$dfVarssub 变量 如下所示:

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%09d "$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 %11d %11d %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" )

关于arrays - Bash - 如何将列表分配给数组成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71245741/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com