假设我有两个字符串,一个用作空格分隔键的字符串,另一个用作第一个键中每个键的关联空格分隔值:
KEYS="key_1 key_2 key_3"
VALS="value1 aDifferentValue_2 theFinalValue"
因此,在这种情况下,key_1
中的$KEYS
的关联值为value1
,key_2
的关联值为aDifferentValue_2
,依此类推。假设有问题的密钥是key_2
,存储在变量$FIELD
中,使用sed和/或awk最简单的方法是根据其单词位置查找该值,该值必须为{{1} }?有没有办法使用aDifferentValue_2
的子串作为键并使用$KEYS
作为值来创建关联数组?
答案 0 :(得分:2)
由于这是标记为bash
,因此您可以拥有实际的关联数组(bash v4):
KEYS="key_1 key_2 key_3"
VALS="value1 aDifferentValue_2 theFinalValue"
keys=( $KEYS )
vals=( $VALS )
declare -A map
for (( i=0; i<${#keys[@]}; i++ )); do
map["${keys[$i]}"]="${vals[$i]}"
done
for idx in "${!map[@]}"; do
echo "$idx -> ${map[$idx]}"
done
输出
key_1 -> value1
key_2 -> aDifferentValue_2
key_3 -> theFinalValue
如果您没有bash v4,仍然可以使用keys
和vals
索引数组,并且:
get_key_idx() {
for (( i=0; i<${#keys[@]}; i++ )); do
if [[ "$key" = "${keys[$i]}" ]]; then
echo $i
return 0
fi
done
return 1
}
key="key_2"
if idx=$(get_key_idx $key); then
echo "$key -> ${vals[$idx]}"
else
echo "no mapping for $key"
fi
答案 1 :(得分:1)
怎么样:
变量:
/home/sirch>KEYS="key_1 key_2 key_3"
/home/sirch>VALS="value1 aDifferentValue_2 theFinalValue"
代码:
/home/sirch>cat s.awk
BEGIN{
split(keystring,key," ");
split(valstring,temp," ")
for(i=1;i<=length(key);i++)val[key[i]]=temp[i]
}
END{print val["key_2"]}
输出:
/home/sirch>awk -v "keystring=$KEYS" -v "valstring=$VALS" -v "query=key_02" -f s.awk f
aDifferentValue_2
首先设置shell变量KEYS和VALS。然后将它们作为字符串导出到akw。 然后将这些字符串拆分为空格,将结果数组保存在“key”和“temp”中。 temp ist用于创建vinal hashmap“val”。现在,您可以查询val [“key_1”]等,以从VALS-shell字符串中获取相应的值。
要从shell脚本运行此命令,只需将awk脚本保存到文件即可。然后将shell变量查询设置为查询字符串,并使用此变量从shell脚本中调用awk-script。你将给出一个虚拟文件,这里是“f”,作为awk的参数,使这个工作。
HTH Chris
答案 2 :(得分:1)
Pure POSIX shell:
#!/bin/sh # set -x assoc() { keys="$1 " values="$2 " key=$3 while [ -n "$keys" -a -n "$values" ]; do key_=${keys%% *} keys=${keys#* } value_=${values%% *} values=${values#* } if [ $key_ = $key ]; then echo $value_ return 0 fi done return 1 } keys='a b c' values='1 2 3' key=b echo Value for key $key is _`assoc "$keys" "$values" "$key"`_ keys='a b c' values='1 2 3' key=xxx echo Value for key $key is _`assoc "$keys" "$values" "$key"`_ keys='a b c' values='1 2 3 4 5' key=c echo Value for key $key is _`assoc "$keys" "$values" "$key"`_ keys='a b c' values='1 2' key=c echo Value for key $key is _`assoc "$keys" "$values" "$key"`_
运行时:
bash# ./1.sh Value for key b is _2_ Value for key xxx is __ Value for key c is _3_ Value for key c is __
答案 3 :(得分:0)
这是一个仅限bash的选择:
#!/bin/bash -x
KEYS="key_1 key_2 key_3"
VALS="value1 aDifferentValue_2 theFinalValue"
assoc() {
read fkey rkeys
read fval rvals
if [ "X$fkey" == "X$1" ] ; then echo $fval; exit 0; fi
if [ "X$rkeys" == "X" ] ; then exit 1; fi
echo -e "$rkeys\n$rvals" | assoc $1
}
echo -e "$KEYS\n$VALS" | assoc key_2
答案 4 :(得分:0)
另一个AWK解决方案(可能更短?)
echo "$keys $vals"|awk '{t=NF/2;for(i=1;i<=t;i++)a[$i]=$(i+t);}{print a[KeyYouWANT]}'
<强>试验:强>
kent$ keys="key_1 key_2 key_3"
kent$ vals="value1 aDifferentValue_2 theFinalValue"
kent$ echo "$keys $vals"|awk '{t=NF/2;for(i=1;i<=t;i++)a[$i]=$(i+t);} END{print a["key_2"]}'
aDifferentValue_2
您也可以将所需的keyStr放在变量
中kent$ want=key_3
kent$ echo "$keys $vals"|awk -v x=$want '{t=NF/2;for(i=1;i<=t;i++)a[$i]=$(i+t);} END{print a[x]}'
theFinalValue
或者您想要查看完整列表:
kent$ echo "$keys $vals"|awk '{t=NF/2;for(i=1;i<=t;i++)a[$i]=$(i+t);} END{for(x in a)print x,a[x]}'
key_1 value1
key_2 aDifferentValue_2
key_3 theFinalValue
答案 5 :(得分:0)
这是一个sed解决方案:
keys="key_1 key_2 key_3" values="value_1 value_2 value_3" key="key_2" # variables used
str="$keys @@$values $key " # keys/values delimit by '@@' add key N.B. space after key!
sed -rn ':a;s/^(\S* )(.*@@)(\S* )(.*)/\2\4\1\3/;ta;s/^@@(\S* ).*\1(\S*).*/\2/p' <<<"$str"
# re-arrange keys/values into a lookup table then match on key using back reference