[英]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
将显示包含93u
或93u+
的字符串
从包含所需键/值对的平面文件开始:
# 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.