Фильтрация текста по awk или bash с некоторыми конкретными условиями

У меня есть выход (из хорошо известного btmon инструмент), как в примере ниже, и мне нужно проанализировать его и получить некоторую информацию из него следующим образом: если UUID представлен в разделе HCI event: и это равняется 32f9169f-4feb-4883-ade6-1f0127018db3 затем принять значение Address: а также RSSI: поля и собрать их вместе и сделать новую линию. Также каждый экземпляр должен быть помещен в определенный файл в соответствии с номером [hci] (та же строка, что и для события HCI). Например, из каждого события HCI hci 0 (отвечающего описанным условиям) он переходит в файл hci0.txt из hci1. в файл-hci1.txt и так далее для всех hciX в таком формате, как для hci0 (.txt):

A0: E6: F8: 48: 38: 6F AB

A0: E6: F8: 48: 87: DA B6

для hci1 (.txt):

A0: E6: F8: 48: 32: 94 C3

A0: E6: F8: 48: EF: 78 BA

Итак, вот поток или файл, который мне нужно проанализировать описанным способом:

> HCI Event: LE Meta Event (0x3e) plen 43                       [hci1] 4.746057
      LE Advertising Report (0x02)
        Num reports: 1
        Event type: Non connectable undirected - ADV_NONCONN_IND (0x03)
        Address type: Public (0x00)
        Address: A0:E6:F8:48:32:94 (Texas Instruments Inc)
        Data length: 31
        Flags: 0x05
          LE Limited Discoverable Mode
          BR/EDR Not Supported
        Company: not assigned (37984)
          Data: 3248f8e6a000
        128-bit Service UUIDs (complete): 1 entry
          32f9169f-4feb-4883-ade6-1f0127018db3
        RSSI: -61 dBm (0xc3)
> HCI Event: LE Meta Event (0x3e) plen 43                       [hci0] 5.198878
      LE Advertising Report (0x02)
        Num reports: 1
        Event type: Non connectable undirected - ADV_NONCONN_IND (0x03)
        Address type: Public (0x00)
        Address: A0:E6:F8:48:38:6F (Texas Instruments Inc)
        Data length: 31
        Flags: 0x05
          LE Limited Discoverable Mode
          BR/EDR Not Supported
        Company: not assigned (28512)
          Data: 3848f8e6a000
        128-bit Service UUIDs (complete): 1 entry
          32f9169f-4feb-4883-ade6-1f0127018db3
        RSSI: -85 dBm (0xab)
> HCI Event: LE Meta Event (0x3e) plen 43                       [hci1] 5.819728
      LE Advertising Report (0x02)
        Num reports: 1
        Event type: Non connectable undirected - ADV_NONCONN_IND (0x03)
        Address type: Public (0x00)
        Address: A0:E6:F8:48:EF:78 (Texas Instruments Inc)
        Data length: 31
        Flags: 0x05
          LE Limited Discoverable Mode
          BR/EDR Not Supported
        Company: not assigned (30816)
          Data: ef48f8e6a000
        128-bit Service UUIDs (complete): 1 entry
          32f9169f-4feb-4883-ade6-1f0127018db3
        RSSI: -70 dBm (0xba)
> HCI Event: LE Meta Event (0x3e) plen 43                       [hci0] 6.011983
      LE Advertising Report (0x02)
        Num reports: 1
        Event type: Non connectable undirected - ADV_NONCONN_IND (0x03)
        Address type: Public (0x00)
        Address: A0:E6:F8:48:87:DA (Texas Instruments Inc)
        Data length: 31
        Flags: 0x05
          LE Limited Discoverable Mode
          BR/EDR Not Supported
        Company: not assigned (55904)
          Data: 8748f8e6a000
        128-bit Service UUIDs (complete): 1 entry
          32f9169f-4feb-4883-ade6-1f0127018db3
        RSSI: -74 dBm (0xb6)

3 ответа

Решение

В Ruby, awk, Python, Perl вы можете:

  1. Разделить текст на блоки;
  2. Проверьте каждый блок для трех тестов регулярных выражений, которые вы описываете;
  3. Разобрать блок;
  4. Распечатать в соответствующий файл.

Первая часть помогает с помощью sed добавить \n между блоками, а затем использовать awk обрабатывать каждый блок. Вот sed а также awk производят блоки (2 из них), которые представляют интерес:

$ sed 's / ^> / \
& / 'файл | awk -v RS="" -v FS="\n" '
  /UUIDs/ && /32f9169f-4feb-4883-ade6-1f0127018db3/ && /\[hci[01]\]/' 

Теперь добавьте awk к тому к этому блоки в два файла:

$ sed 's/^>/\
&/' file | 
awk -v RS="" -v FS="\n" '
  /UUIDs/ && /32f9169f-4feb-4883-ade6-1f0127018db3/ && /\[hci[0-9]+\]/ {
      s1=s2=fo=""
      for (i=1;i<=NF;i++) {
            if (match($i,/\[hci[0-9]+/))
                 fn=substr($i,RSTART+1,RLENGTH-1)
            if (match($i,/Address: /))
                 s1=substr($i,RSTART+RLENGTH, 17)
            else if (match($i,/ RSSI:/)) {
                 match($i,/\(0x[^)]+\)/)
                 s2=toupper(substr($i,RSTART+3, RLENGTH-4))  
            }
        }
     fo="file-" fn ".txt"   
     print s1 " " s2 " => " fo
     print s1 " " s2 > fo
}'    

$ cat file-hci0.txt
A0:E6:F8:48:38:6F AB
A0:E6:F8:48:87:DA B6 
$ cat file-hci1.txt
A0:E6:F8:48:32:94 C3
A0:E6:F8:48:EF:78 BA  

Файл _сценарий:

$1 == ">" {
          cnt++
          for (i=1;i<=NF;i++) {
                if ( $i ~ /\[.*\]/ ) {
                                 hci[cnt]=substr($i,2,length($i)-2)
                        }
                }
        }
$1 == "Address:" {
           add[cnt]=$2
        }
$0 ~ /32f9169f-4feb-4883-ade6-1f0127018db3/ {
           fnd[cnt]=""
        }
$1 == "RSSI:"   {
           str=substr($4,length($4)-2)
           gsub("\)","",str)
           rssi[cnt]=toupper(str)
        }
END {
           for (i in fnd) {
                        print add[i]" "rssi[i] > "file-"hci[i]".txt"
                }
    }




awk -f scriptfile filename

При использовании awk и использовании файла сценария для кода awk, когда мы встречаем ">", это означает новый блок данных, и поэтому мы увеличиваем переменную cnt. Затем мы перебираем каждое поле в этой строке и сравниваем его с чем угодно, начиная с [и заканчивая]. Этот текст затем удаляет [and] с помощью substr и добавляется в массив hci, проиндексированный с помощью cnt. Затем мы сохраняем все адреса в массиве add и текст RSSI (отформатированный с помощью substr и gsub) в rssi. Если MAC-адрес совпадает, создается массив fnd. Все массивы индексируются cnt. Наконец, мы перебираем fnd и извлекаем другие данные из других массивов, распечатывая требуемый вывод и перенаправляя для создания необходимых файлов.

Попробуйте и дайте мне знать, если это поможет вам.

awk '/> HCI Event/ && a && b{print val1,toupper(substr(val2,4,2));a=b=""} /> HCI Event/{a=1;} /UUID/ && a{getline;sub(/^[[:space:]]+/,"");if($0 == "32f9169f-4feb-4883-ade6-1f0127018db3"){b=1}} /Address/ && a{val1=$2;} /RSSI/ && a{val2=$4;}'  Input_file

Слишком скоро добавит не одну линейную форму решения.

РЕДАКТИРОВАТЬ: Добавление не один вкладыш формы решения тоже сейчас.

awk '/> HCI Event/ && a && b{
        print val1,toupper(substr(val2,4,2));a=b=""}
    /> HCI Event/{a=1;}
    /UUID/ && a  {
        getline;
        sub(/^[[:space:]]+/,"");
        if($0 == "32f9169f-4feb-4883-ade6-1f0127018db3"){b=1}
                 }
    /Address/ && a{val1=$2;}
    /RSSI/ && a{val2=$4;}
    '   Input_file
Другие вопросы по тегам