簡體   English   中英

記錄上的ksh數組

[英]ksh array over records

我需要基於此表關聯值。

KEYS    VALS
----    ----
keyp    val1
keyp    val2
keyp    val3
keyp    val6
keyc    val4
keym    val4
keys    val8
keyr    val8
keyb    val5

在我的ksh中,當傳遞的參數是KEY時,我想遍歷該表,以便獲得所有可能的VALS。 例如,如果parm_key =“ keyp”,我的迭代將產生val1,val2,val3,val6。 偽代碼:

for iLoop in "${!KEYS2VALS[@]}"
do
    if [[ KEYS2VALS[iLoop] = $parm_key ]];then
        print "found value match=$KEYS2VALS[iLoop].VAL"
    fi
done

如果$ parm_key =“ keyp”,則該psuedocode的輸出應為以下內容

found value match=val1
found value match=val2
found value match=val3
found value match=val6

假設您可以訪問ksh93(因此我們可以使用關聯數組)...

注意:對於某些較新的操作系統,/ bin / ksh ksh93(已重命名或符號鏈接到ksh93); 在這種情況下, ksh --version將顯示包含93u93u+的字符串

從包含所需鍵/值對的平面文件開始:

# sample data file
$ cat key.vals
keyp val1
keyp val2
keyp val3
keyp val6
keyc val4
keym val4
keys val8
keyr val8
keyb val5

一種可能的ksh93 shell腳本:

$ cat kv
#!/bin/ksh93

# grab and verify an input key

parm_key=$1
[[ "${parm_key}" = '' ]] && printf "Usage: kv <parm_key>\n" && exit

# declare associative array 'keys2vals'

unset      keys2vals
typeset -A keys2vals

# load the key/value pairs into the associative array 'keys2vals'

while read -r key val
do
        keys2vals[${key}]="${keys2vals[${key}]} ${val}"
done < key.vals

# for debug purposes only: display array

printf "All key/value pairs:\n\n"
for key in ${!keys2vals[@]}
do
        echo "key=${key} : value=${keys2vals[${key}]}"
done
echo ""

# print the values associated with ${parm_key}

printf "All values for key = ${parm_key}:\n\n"
for val in ${keys2vals[${parm_key}]}
do
        echo "found value match=${val}"
done

運行中的腳本:

$ kv
Usage: kv <parm_key>

$ kv keyp
All key/value pairs:

key=keyb : value= val5
key=keyc : value= val4
key=keym : value= val4
key=keyp : value= val1 val2 val3 val6
key=keyr : value= val8
key=keys : value= val8

All values for key = keyp:

found value match=val1
found value match=val2
found value match=val3
found value match=val6

# commenting out the debug loop ...

$ kv keyb
All values for key = keyb:

found value match=val5

$ kv keyc
All values for key = keyc:

found value match=val4

$ kv keym
All values for key = keym:

found value match=val4

$ kv keyr
All values for key = keyr:

found value match=val8

$ kv keys
All values for key = keys:

found value match=val8

在此示例中,我設法獲得了二維關聯數組:

首先,讓我們將數據放入文件中

$ cat table.txt
KEYS    VALS
----    ----
keyp    val1
keyp    val2
keyp    val3
keyp    val6
keyc    val4
keym    val4
keys    val8
keyr    val8
keyb    val5

我們將使用一個名為“表”的關聯數組

typeset -A table

現在,讓我們填充數組。 棘手的一點是,我們需要聲明數組的每個元素本身就是一個關聯數組。 當我們遇到不在“表”中的鍵時,我們需要這樣做:

i=0
sed '1,2d' table.txt | while read -r key value; do
    [[ -z "${table[$key]+not set}" ]] && typeset -A table[$key]
    table[$key][$value]=$((++i))
done

現在,讓我們看看表數組中有什么

for key in "${!table[@]}"; do 
    for subkey in "${!table[$key][@]}"; do 
        printf "%s\t%s\t%s\n" "$key" "$subkey" "${table[$key][$subkey]}"
    done
done
keyb    0   
keyb    val5    9
keyc    0   
keyc    val4    5
keym    0   
keym    val4    6
keyp    0   
keyp    val1    1
keyp    val2    2
keyp    val3    3
keyp    val6    4
keyr    0   
keyr    val8    8
keys    0   
keys    val8    7

一切都很好,除了每個頂級鍵還具有一個子鍵“ 0”。 看起來很奇怪,但是我認為這就是在ksh中實現變量的方式。 甚至簡單的標量變量也可以引用為索引為0的數組:

$ foo=bar
$ echo "$foo"
bar
$ echo "${foo[0]}"
bar
$ printf "%s\n" "${!foo[@]}"
0

問題的核心:檢索特定鍵的值:

parm_key="keyp"
typeset -a values
for val in "${!table[$parm_key][@]}"; do
    [[ $val = "0" ]] || values+=("$val")
done
printf "%s\n" "${values[@]}"
val1
val2
val3
val6

我只是意識到這太復雜了。 我們不需要關聯數組的關聯數組。 我們需要索引數組的關聯數組:

$ unset table
$ typeset -A table
$ sed '1,2d' table.txt | while read -r key value; do table[$key]+=("$value"); done
$ printf "%s\n" "${!table[@]}"
keyb
keyc
keym
keyp
keyr
keys
$ for key in "${!table[@]}"; do for val in "${table[$key][@]}"; do printf "%s\t%s\n" "$key" "$val"; done; done
keyb    val5
keyc    val4
keym    val4
keyp    val1
keyp    val2
keyp    val3
keyp    val6
keyr    val8
keys    val8
$ printf "%s\n" "${table[$parm_key][@]}"
val1
val2
val3
val6

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM