我发现了一个无法解决的奇怪问题。
我需要在一个变量中提取一些值,这些值在一个字符串之后。
本例中的变量名称为:DSLSTATE
这里有一个值的例子:
NewEnable 1
NewStatus Up
NewDataPath Fast
NewUpstreamCurrRate 21598
NewDownstreamCurrRate 170788
NewUpstreamMaxRate 25692
NewDownstreamMaxRate 170788
NewUpstreamNoiseMargin 90
NewDownstreamNoiseMargin 60
NewUpstreamAttenuation 150
NewDownstreamAttenuation 170
NewATURVendor 41564d00
NewATURCountry 0400
NewUpstreamPower 486
NewDownstreamPower 514
这不是一个数组。
提取我想要的值:
ATTUPSTREAM=$(echo "$DSLTATE" | awk '{for (I=1;I<NF;I++) if ($I == "NewUpstreamAttenuation") print $(I+1)}')
在本例中,该值应为150,但始终为空。
奇怪的是,我可以用同一个命令从同一个变量中提取所有值,只有一个例子例外。如果我在终端上执行相同的命令,它就工作了,在脚本中就不工作了。
这里的脚本摘录:
UPSTREAM=$(echo $DSLSTATE | awk '{for (I=1;I<NF;I++) if ($I == "NewUpstreamCurrRate") print $(I+1)}')
DOWNSTREAM=$(echo $DSLSTATE | awk '{for (I=1;I<NF;I++) if ($I == "NewDownstreamCurrRate") print $(I+1)}')
ATTUPSTREAM=$(echo $DSLTATE | awk '{for (I=1;I<NF;I++) if ($I == "NewUpstreamAttenuation") print $(I+1)}')
ATTDOWNSTREAM=$(echo $DSLSTATE | awk '{for (I=1;I<NF;I++) if ($I == "NewDownstreamAttenuation") print $(I+1)}')
SNRUPSTREAM=$(echo $DSLSTATE | awk '{for (I=1;I<NF;I++) if ($I == "NewUpstreamNoiseMargin") print $(I+1)}')
SNRDOWNSTREAM=$(echo $DSLSTATE | awk '{for (I=1;I<NF;I++) if ($I == "NewDownstreamNoiseMargin") print $(I+1)}')
以下是结果:
ATTUPSTREAM=
ATTDOWNSTREAM=170
SNRUPSTREAM=40
SNRDOWNSTREAM=50
也许DSLSTATE变量中的值之间的间距有一些奇怪的字符?
希望有人能启发我。
-
不要对awk或未导出的shell变量使用所有大写名称,以避免与内置变量发生冲突和其他原因,例如,有关shell问题,请参阅正确的Bash和shell脚本变量大写。
-
当输入为总是在标记值对中。
-
当你有通用代码时在一个函数中,不要重复多次-据我们所知代码中可能存在控制字符或其他问题一个标签值。
首先更改代码以使用一个简单的查找函数:
$ tag2val() { echo "$DSLSTATE" | awk -v tag="$1" '$1==tag { print $2 }'; }
$ tag2val NewDataPath
Fast
$ tag2val NewUpstreamAttenuation
150
如果您还有问题,请告诉我们。如果你这样做了,那么编辑你的问题以显示echo "$DSLSTATE" | cat -Ev
的输出。
如果使用Bash,另一个选项可以是将DSLSTATE
转换为关联数组。之后,将更容易获得基于密钥的值:
#!/bin/bash
DSLSTATE='NewEnable 1
NewStatus Up
NewDataPath Fast
NewUpstreamCurrRate 21598
NewDownstreamCurrRate 170788
NewUpstreamMaxRate 25692
NewDownstreamMaxRate 170788
NewUpstreamNoiseMargin 90
NewDownstreamNoiseMargin 60
NewUpstreamAttenuation 150
NewDownstreamAttenuation 170
NewATURVendor 41564d00
NewATURCountry 0400
NewUpstreamPower 486
NewDownstreamPower 514'
declare -A kv
while read k v; do
kv[$k]=$v
done <<< $DSLSTATE
echo "NewDownstreamPower: ${kv[NewDownstreamPower]}"
上面的代码将导致:
NewDownstreamPower: 514