2012-03-15 2 views
0

В сценарии bash я пытаюсь извлечь некоторые данные из вывода команды (в моем случае iwconfig).Извлечение полей данных из вывода команды с использованием bash

Я хотел бы создать файл csv с собранными значениями. Нравится:

Timestamp,BitRate,LinkQuality,SignalLevel,Missed beacon,... 
1,270 Mb/s,100/100,-51 dBm,0,... 
2,300 Mb/s,90/100,-43 dBm,0,... 

Поля разделены пробелами на выходе iwconfig. Если бы я мог установить переменную IFS в два пробела, моя проблема была бы решена. Но я не знаю, работает ли это. Что вы будете использовать для этого? Awk или sed?

С наилучшими пожеланиями

+0

sed звучит так, как будто это выполнит работу (при условии, что у вас нет сложных правил экранирования для пробелов внутри строк). –

+0

sed хороший. cut может быть неэффективен, потому что его -d = DELIM требует один разделитель, поэтому два пробела могут выглядеть как дополнительное поле. Можете ли вы опубликовать ввод? – octopusgrabbus

+0

Пожалуйста, введите пример ввода. Однако разделитель полей awk по умолчанию - «whitespace», поэтому это не проблема, а это всего 2 пробела. –

ответ

0

Я думаю, что это может работать:

s=$(iwconfig $Interface) 
    s=${s//  /} 
    s=${s// /,} 
    OIFS="$IFS" 
    IFS=',' 
    arrIN=(${s// /,}) 
    IFS=$OIFS 

    for value in "${arrIN[@]}"; do 
    echo Value: $value 
    done 

я получаю этот выход:

Value: wlan0 
Value: 
Value: IEEE 802.11abgn 
Value: ESSID:"Top Gear" 
Value: 
Value: Mode:Managed 
Value: Frequency:2.452 GHz 
Value: Access Point: F8:D1:11:71:56:B6 
Value: 
Value: Bit Rate=1 Mb/s 
Value: Tx-Power=15 dBm 
Value: 
Value: Retry 
Value: long limit:7 
Value: RTS thr:off 
Value: Fragment thr:off 
Value: Encryption key:off 
Value: Power Management:off 
Value: Link Quality=49/70 
Value: Signal level=-61 dBm 
Value: 
Value: Rx invalid nwid:0 
Value: Rx invalid crypt:0 
Value: Rx invalid frag:0 
Value: Tx excessive retries:0 
Value: Invalid misc:0 
Value: Missed beacon:0 

Теперь я могу создать нужную мне прямую линию, например.

${arrIN[6]#*":"} 
1

Чтобы ответить на ваш вопрос: я хотел бы использовать AWK. Однако, вероятно, я бы использовал python и одно регулярное выражение для захвата всех параметров в словаре.

Бонус: Я сделал упражнение делать то, что вы хотите в Баш с помощью Grep ГНУ (то регэкспы вам нужно, может изменяться в качестве выходного сигнала iwconfig зависит от устройства):

SLEEP=10 # time to sleep between samples 

while true; do # or launch it as a cron task 
    TIMESTAMP=$(date +'%s') 
    IW=$(iwconfig wlan0) 

    # capture each parameter in a variable 
    IEEE=$(echo "$IW" | grep -oP '(?<=IEEE).[^\s]*') 
    ESSID=$(echo "$IW" | grep -oP '(?<=ESSID:).[^\s]*') 
    BITRATE=$(echo "$IW" | grep -oP '(?<=Bit Rate=)\d+\s.[^\s]+(?=[\s]+Tx)') 
    TXPOWER=$(echo "$IW" | grep -oP '(?<=Tx-Power=)\d+\s.*') 
    RLL=$(echo "$IW" | grep -oP '(?<=limit:)\d') 
    RTSTHR=$(echo "$IW" | grep -oP '(?<=RTS thr:).+(?=[ ]+Fra)') 
    FRAGTHR=$(echo "$IW" | grep -oP '(?<=Fragment thr:).+') 
    TXPOWER=$(echo "$IW" | grep -oP '(?<=Tx-Power=)\d+ .*') 
    PM=$(echo "$IW" | grep -oP '(?<=Management:).*') 
    LQ=$(echo "$IW" | grep -oP '(?<=Quality=)\d+/\d+') 
    SIGLEV=$(echo "$IW" | grep -oP '(?<=level=).*') 
    RXNWID=$(echo "$IW" | grep -oP '(?<=nwid:)\d+') 
    RXCRYPT=$(echo "$IW" | grep -oP '(?<=crypt:)\d+') 
    RXFRAG=$(echo "$IW" | grep -oP '(?<=frag:)\d+') 
    RTERET=$(echo "$IW" | grep -oP '(?<=retries:)\d+') 
    RTIMISC=$(echo "$IW" | grep -oP '(?<=misc:)\d+') 
    RTMBEAC=$(echo "$IW" | grep -oP '(?<=beacon:)\d+') 

    #line 
    echo $TIMESTAMP,$BITRATE,$LQ,$SIGLEV,$RTMBEAC,... 
    sleep $SLEEP 
done 

Пример вывода :

1331848207,54 Mb/s,70/70,-37 dBm ,0,... 
1331848217,54 Mb/s,70/70,-35 dBm ,0,... 
1331848227,54 Mb/s,70/70,-34 dBm ,0,... 
1331848237,54 Mb/s,70/70,-39 dBm ,0,... 
1331848247,54 Mb/s,70/70,-35 dBm ,0,... 
1331848257,54 Mb/s,70/70,-37 dBm ,0,... 
+0

Я не знал, что выход iwconfig зависит от устройства. Спасибо за подсказку! Возможно, я должен был объяснить ранее: сценарий будет работать на empedded linux system (Gumstix), и я думаю, что grep читает переменную каждый раз полностью. Поскольку я знаю, где поля, я думал об использовании массива. Таким образом, я читаю выходное слово в слово в массив и могу получить доступ к конкретным полям напрямую, не читая все содержимое переменной снова и снова. – Powderking