-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 youHi:SP:how:SP:are:SP:you
  3. マップは、最初に指定された引数という名前の変数に格納されます。したがって、この行は変数に次のテキストを追加します-$ key = $ valueここで、keyは2番目の引数であり、valueはエスケープされた3番目の引数です
  4. getは、2番目の引数として提供されたキーの値を値に格納するだけです(最初の引数はマップの名前です)

理解を深めるために、各操作の後にマップに使用することを決定した変数を印刷してみてください。あなたが見るのは簡単です;)これがそれを明らかにすることを願っています。

于 2012-10-11T12:18:13.217 に答える
1

あなたが強調したすべての行を説明しようと思います:

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

正確に3つの引数がない場合は、エラーで終了します。

    mapName=$1; key=$2; value=`echo $3 | sed -e "s/ /:SP:/g"`  #dont understand 
  1. $mapName最初の引数の値で変数を設定します
  2. $key2番目の引数の値で変数を設定します
  3. $valueスペースを文字列に置き換えた後、変数を3番目の引数の値で設定します:SP:

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

$mapこれにより、変数の値が最初に出現し$key=その後にスペース以外の文字--が続き、$key次に文字列、値=、最後に。の値が追加されて変数が編集されます$value

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

これにより、その行によって生成された文字列が評価されます。isと$mapNameisであるとすると、bashが評価する文字列は次のとおりです。myMap$mapvalue

myMap="value"

したがって、実際には変数を設定し、その名前はパラメーターによって渡されます。

    map=${!mapName}

これ$mapにより、の値と同じ名前の変数の値が変数に設定され$mapNameます。例:$mapNamea$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 に答える