我在这里找到了关联数组的实现,并想了解代码的实际作用。这是我不明白的代码片段,希望得到解释。 '
put() {
if [ "$#" != 3 ]; then exit 1; fi
mapName=$1; key=$2; value=`echo $3 | sed -e "s/ /:SP:/g"` #dont understand
eval map=""$$mapName"" **#dont understand**
map="`echo "$map" | sed -e "s/--$key=[^ ]*//g"` --$key=$value" #dont understand
eval $mapName=""$map"" #dont understand
}
get() {
mapName=$1; key=$2
map=${!mapName}
#dont understand
value="$(echo $map |sed -e "s/.*--${key}=([^ ]*).*/1/" -e 's/:SP:/ /g' )"
}
getKeySet() {
if [ "$#" != 1 ];
then
exit 1;
fi
mapName=$1;
eval map=""$$mapName""
keySet=`
echo $map |
sed -e "s/=[^ ]*//g" -e "s/([ ]*)--/1/g" #dont understand
`
}
谢谢。
所以首先按不明白的顺序:
- 这只是检查您始终有 3 个函数参数,如果提供了不同的数字,则以 1(错误)退出
- 这通过用
:SP:
替换空格字符来逃避空格字符,因此Hi how are you
变得Hi:SP:how:SP:are:SP:you
- 映射存储在一个变量中,其名称是提供的第一个参数。所以这一行将以下文本添加到 var 中 --$key=$value这里 key 是第二个参数,值是转义的第三个参数
- get 简单地将作为第二个参数提供的键的值存储在值中(第一个是映射的名称)
为了更好地理解,请尝试在每次操作后打印您决定用于地图的变量。你很容易看到;) 希望这能说清楚。
我将尝试解释您突出显示的每一行:
if [ "$#" != 3 ]; then exit 1; fi #dont understand
如果没有正好三个参数,请退出并显示错误。
mapName=$1; key=$2; value=`echo $3 | sed -e "s/ /:SP:/g"` #dont understand
- 使用第一个参数的值设置变量
$mapName
- 使用第二个参数的值设置变量
$key
用 字符串
:SP:
替换空格后,使用第三个参数的值设置变量$value
。map="`echo "$map" | sed -e "s/--$key=[^ ]*//g"` --$key=$value" #dont understand
这将编辑$map
变量,方法是删除$key
值的第一个匹配项,后跟=
然后是非空格字符,然后将字符串追加--
后跟$key
的值,然后是=
的值,最后是$value
的值。
eval $mapName=""$map"" #dont understand
这将计算由该行生成的字符串。假设$mapName
是myMap
的,$map
是value
的,bash 将计算的字符串为:
myMap="value"
因此,它实际上将设置一个变量,其名称将由参数传递。
map=${!mapName}
这将设置变量$map
值,该值与$mapName
中的值同名的变量。示例:假设$mapName
有a
,那么$map
最终会得到a
的内容。
value="$(echo $map |sed -e "s/.*--${key}=([^ ]*).*/1/" -e 's/:SP:/ /g' )"
在这里,我们将$value
变量的值设置为$map
变量的值,经过几次编辑:
- 仅提取在 sed 表达式的括号之间的表达式中指定的内容,该表达式与非空格字符匹配。它前面的文本指定匹配的开始位置,因此在这种情况下,空格必须在字符串之后开始,
--
后跟$key
变量的值,后跟=
。开头和结尾的".*"与行的其余部分匹配,用于在之后删除它们。 恢复空格,即用实际空格替换
:SP:
。eval map=""$$mapName""
这将创建一个值为"$mapName"的字符串,即一美元,后跟 mapName 中包含的字符串,用双引号括起来。计算时,这将获取名称为$mapName
内容的变量的值。
希望这有所帮助=)
Bash,从版本4及更高版本开始,就内置了关联数组。
要使用它们,您需要声明一个带有declare -A
#!/usr/bin/env bash
declare -A arr # 'arr' will be an associative array
# now fill it with: arr['key']='value'
arr=(
[foo]="bar"
["nyan"]="cat"
["a b"]="c d"
["cookie"]="yes please"
["$USER"]="$(id "$LOGNAME")"
)
# -- cmd -- -- output --
echo "${arr[foo]}" # bar
echo "${arr["a b"]}" # c d
user="$USER"
echo "${arr["$user"]}" # uid=1000(c00kiemon5ter) gid=100...
echo "${arr[cookie]}" # yes please
echo "${arr[cookies]}" # <no output - empty value> :(
# keys and values
printf '%sn' "${arr[@]}" # print all elements, each on a new line
printf '%sn' "${!arr[@]}" # print all keys, each on a new line
# loop over keys - print <key :: value>
for key in "${!arr[@]}"
do printf '%s :: %sn' "$key" "${arr["$key"]}"
done
# you can combine those with bash parameter expansions, like
printf '%sn' "${arr[@]:0:2}" # print only first two elements
echo "${arr[cookie]^^}" # YES PLEASE