BASH提取变量Not文件中字符串后的值



我发现了一个无法解决的奇怪问题。

我需要在一个变量中提取一些值,这些值在一个字符串之后。

本例中的变量名称为: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变量中的值之间的间距有一些奇怪的字符?

希望有人能启发我。

  1. 不要对awk或未导出的shell变量使用所有大写名称,以避免与内置变量发生冲突和其他原因,例如,有关shell问题,请参阅正确的Bash和shell脚本变量大写。

  2. 当输入为总是在标记值对中。

  3. 当你有通用代码时在一个函数中,不要重复多次-据我们所知代码中可能存在控制字符或其他问题一个标签值。

首先更改代码以使用一个简单的查找函数:

$ 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

最新更新