bash中的关联数组

bash中的关联数组,bash,shell,sed,hashtable,Bash,Shell,Sed,Hashtable,我找到了关联数组的一个实现,希望了解代码的实际功能。下面是我不理解的代码片段,请解释一下。 " 谢谢。所以先按不理解的顺序: 这只是检查函数始终有3个参数,如果提供了不同的参数,则退出1(错误) 通过将空格字符替换为:SP:,这样你好就变成了你好:SP:how:SP:you 映射存储在一个var中,其名称是提供给put的第一个参数。所以这一行向var添加了以下文本--$key=$value,这里key是第二个参数,value是转义的第三个参数 get只是将作为第二个参数提供的键的值存储在valu

我找到了关联数组的一个实现,希望了解代码的实际功能。下面是我不理解的代码片段,请解释一下。 "


谢谢。

所以先按不理解的顺序:

  • 这只是检查函数始终有3个参数,如果提供了不同的参数,则退出1(错误)
  • 通过将空格字符替换为
    :SP:
    ,这样
    你好
    就变成了
    你好:SP:how:SP:you
  • 映射存储在一个var中,其名称是提供给put的第一个参数。所以这一行向var添加了以下文本--$key=$value,这里key是第二个参数,value是转义的第三个参数
  • get只是将作为第二个参数提供的键的值存储在value中(第一个参数是映射的名称)
  • 为了更好地理解,请尝试在每次操作后打印决定用于映射的变量。你会发现这很容易;)
    希望这能说明问题。

    我将尝试解释您强调的每一行:

        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
    的值,然后删除
    =/code>,最后是
    $value
    的值

        eval $mapName="\"$map\""  #dont understand 
    
    这将计算该行生成的字符串。假设
    $mapName
    myMap
    $map
    value
    ,bash将计算的字符串是:

    myMap="value"
    
    因此,它将实际设置一个变量,其名称将由一个参数传递

        map=${!mapName}
    
    这将使用与
    $mapName
    中的值同名的变量值设置变量
    $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 '%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
    
    #/usr/bin/env bash
    声明-arr#“arr”将是关联数组
    #现在用:arr['key']='value'填充它
    啊=(
    [foo]=“bar”
    [“年”]=“猫”
    [“a b”]=“c d”
    [“cookie”]=“是的,请”
    [“$USER”]=“$(id“$LOGNAME”)”
    )
    #--cmd--output--
    回声“${arr[foo]}”条
    回音“${arr[“ab”]}”#cd
    user=“$user”
    echo“${arr[“$user”]}”#uid=1000(c00kiemon5ter)gid=100。。。
    回音“${arr[cookie]}”#是的,请回答
    回显“${arr[cookies]}”:(
    #键和值
    printf'%s\n'${arr[@]}#打印所有元素,每个元素都在新行上
    printf“%s\n”${!arr[@]}“#打印所有键,每一个都在新行上
    #循环键-打印
    对于“${!arr[@]}”中的键
    是否打印“%s::%s\n”“$key”“${arr[“$key”]}”
    完成
    #您可以将它们与bash参数扩展相结合,如
    printf'%s\n'${arr[@]:0:2}只打印前两个元素
    回音“${arr[cookie]^^}”是的
    
    bash
    版本4(iirc)及更高版本具有内置的关联数组。将它们与
    声明-A
    一起使用。map=“\”\$$mapName\”是什么意思?为什么不能只是map=$mapName它实际上创建了一个值为
    “$mapName”的字符串
    ,即一美元,后跟
    $mapName
    内的字符串,并用双引号括起来。我将编辑我的帖子。是的。通过计算结果字符串,我们可以得到由mapName变量命名的变量的值。这与C指针类似(以粗略的方式)。例如:
    myVar=3;mapName=“myVar”;eval“echo\$$mapName\”
    prints 3.明白了。谢谢你的解释。C指针类比清楚地说明了这一点。
    #!/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