-1

我在这里找到了关联数组的实现, 并想了解代码的实际作用。这是我不理解的代码片段,希望能得到解释。'

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 
          ` 
}

谢谢。

4

3 回答 3

2

所以首先按不明白的顺序:

  1. 这只是检查你总是有 3 个函数参数,如果提供了不同的数字,则以 1(错误)退出
  2. 这通过将它们替换为:SP:这样来Hi how are you逃避空格字符Hi:SP:how:SP:are:SP:you
  3. 该映射存储在一个 var 中,其名称是提供给 put 的第一个参数。所以这一行将以下文本添加到 var 中 --$key=$value ,这里的 key 是第二个参数, value 是转义的第三个参数
  4. get 只是将作为第二个参数提供的键的值存储在值中(第一个是地图的名称)

为了更好地理解,请尝试在每次操作后打印您决定用于地图的变量。你会很容易看到 ;) 希望这可以说清楚。

于 2012-10-11T12:18:13.217 回答
1

我将尝试解释您突出显示的每一行:

    if [ "$#" != 3 ]; then exit 1; fi   #dont understand

如果不完全是三个参数,则退出并出错。

    mapName=$1; key=$2; value=`echo $3 | sed -e "s/ /:SP:/g"`  #dont understand 
  1. $mapName使用第一个参数的值设置变量
  2. $key使用第二个参数的值设置变量
  3. $value在用字符串替换空格后,使用第三个参数的值设置变量:SP:

    map="`echo "$map" | sed -e "s/--$key=[^ ]*//g"` --$key=$value"  #dont understand
    

这将编辑$map变量,删除第一次出现的值,$key然后=是非空格字符,然后附加字符串,--然后是 的值$key,然后是=的值$value

    eval $mapName="\"$map\""  #dont understand 

这将评估由该行生成的字符串。假设$mapNameismyMap$mapis value,bash 将评估的字符串是:

myMap="value"

所以它实际上会设置一个变量,它的名称将通过一个参数传递。

    map=${!mapName}

这将$map使用与 中的值同名的变量的值来设置变量$mapName。示例:假设$mapNamehas a$map则以 的内容结束a

    value="$(echo $map |sed -e "s/.*--${key}=\([^ ]*\).*/\1/" -e 's/:SP:/ /g' )"  

在这里,我们将$value变量的值设置为变量的值$map,经过几次编辑:

  1. 仅提取在 sed 表达式中括号之间的表达式中指定的内容,它匹配不是空格的字符。它之前的文本指定匹配应该从哪里开始,所以在这种情况下,空格必须在字符串--之后开始,然后是$key变量的值,然后是=. 开头和结尾的 `.*' 与该行的其余部分相匹配,并用于在之后删除它们。
  2. 恢复空间,即。替换:SP:为实际空格。

    eval map="\"\$$mapName\""
    

这将创建一个值为“$mapName”的字符串,即。一个美元,后跟 mapName 中包含的字符串,用双引号括起来。求值时,这将获取名称为 的内容的变量的值$mapName

希望这会有所帮助=)

于 2012-10-11T12:23:07.107 回答
0

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 '%s\n' "${arr[@]}"     # print all elements, each on a new line
printf '%s\n' "${!arr[@]}"    # print all keys,     each on a new line

# loop over keys - print <key :: value>
for key in "${!arr[@]}"
do printf '%s :: %s\n' "$key" "${arr["$key"]}"
done

# you can combine those with bash parameter expansions, like
printf '%s\n' "${arr[@]:0:2}" # print only first two elements
echo "${arr[cookie]^^}"       # YES PLEASE
于 2012-10-11T16:41:25.020 回答