[英]Linux - parsing data, what language to use
我正在尋找一種基於“列”的格式來解析數據。 我遇到了一些問題,覺得我在“黑客” 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 ++還是其他語言? 還是有更好的方法呢?
謝謝
這應該是您的起點(如果輸入數據是制表符分隔或固定寬度的字段,則可以簡化或刪除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
表示原義的control-M字符。
您的數據包含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$//' )
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.