簡體   English   中英

Linux-解析數據,使用哪種語言

[英]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中創建的,請首先在其上運行dos2unixtr -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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM