我希望从“'”列中解析数据。基于格式。我遇到的问题我觉得自己是“黑客攻击”。用于拉取字符串和数字的bash / awk命令。如果数字/文本有不同的格式,那么脚本可能会意外失败,我会有错误。
数据:
RSSI (dBm): -86 Tx Power: 0
RSRP (dBm): -114 TAC: 4r5t (12341)
RSRQ (dB): -10 Cell ID: efefwg (4261431)
SINR (dB): 2.2
我的方法:
使用bash和awk
#!/bin/bash
DATA_OUTPUT=$(get_data)
RSSI=$(echo "${DATA_OUTPUT}" | awk '$1 == "RSSI" {print $3}')
RSRP=$(echo "${DATA_OUTPUT}" | awk '$1 == "RSRP" {print $3}')
RSRQ=$(echo "${DATA_OUTPUT}" | awk '$1 == "RSRQ" {print $3}')
SINR=$(echo "${DATA_OUTPUT}" | awk '$1 == "SINR" {print $3}')
TX_POWER=$(echo "${DATA_OUTPUT}" | awk '$4 == "Tx" {print $6}')
echo "$SINR"
echo ">$SINR<"
然而上面的输出很奇怪。
2.2 # thats fine!
<2.2 # what??? expecting >4.6<
这样的小事情让我怀疑使用awk和bash来解析数据。我应该使用C ++还是其他语言?或者有更好的方法吗?
谢谢
答案 0 :(得分:1)
这应该是您的起点(如果输入数据是制表符分隔或固定宽度字段,则可以简化或删除match()
):
$ cat file
RSSI (dBm): -86 Tx Power: 0
RSRP (dBm): -114 TAC: 4r5t (12341)
RSRQ (dB): -10 Cell ID: efefwg (4261431)
SINR (dB): 2.2
$ cat tst.awk
{
tail = $0
while ( match(tail,/[^:]+:[[:space:]]+[^[:space:]]+[[:space:]]*([^[:space:]]*$)?/) )
{
nvPair = substr(tail,RSTART,RLENGTH)
sub(/ \([^)]+\):/,":",nvPair) # remove (dB) or (dBm)
sub(/:[[:space:]]+/,":",nvPair) # remove spaces after :
sub(/[[:space:]]+$/,"",nvPair) # remove trailing spaces
split(nvPair,tmp,/:/)
name2value[tmp[1]] = tmp[2] # name2value["RSSI"] = "-86"
tail = substr(tail,RSTART+RLENGTH)
}
}
END {
for (name in name2value) {
value = name2value[name]
printf "%s=\"%s\"\n", name, value
}
}
$ awk -f tst.awk file
Tx Power="0"
RSSI="-86"
TAC="4r5t (12341)"
Cell ID="efefwg (4261431)"
RSRP="-114"
RSRQ="-10"
SINR="2.2"
希望很明显,在match()循环之后的上述脚本中,您可以简单地说print name2value["Tx Power"]
之类的内容来打印该关键短语的值。
如果您的数据是在DOS中创建的,请先在其上运行dos2unix
或tr -d '^M'
,其中^M
表示文字控件-M字符。
答案 1 :(得分:0)
您的数据包含DOS样式\ r \ n行结尾。当你这样做时
echo ">$SINR<"
实际输出实际上是
>4.6\r<
回车符将光标发送回行的开头。
你可以这样做:
DATA_OUTPUT=$(get_data | sed 's/\r$//')
但是我不是一遍又一遍地解析输出,而是像这样重写:
while read -ra fields; do
case ${fields[0]} in
RSSI) rssi=${fields[2]};;
RSRP) rsrp=${fields[2]};;
RSPQ) rspq=${fields[2]};;
SINR) sinr=${fields[2]};;
esac
if [[ ${fields[3]} == "Tx" ]]; then tx_power=${fields[5]}; fi
done < <(get_data | sed 's/\r$//' )