在某些特定条件下通过 awk 或 bash 过滤文本

Filtering text by awk or bash with some specific conditions

我有一个输出(一个众所周知的 btmon 工具),如下例所示,我需要解析它并通过下一种方式从中获取一些信息:如果 UUID 出现在 HCI event: 等于 32f9169f-4feb-4883-ade6-1f0127018db3 然后取 Address:RSSI: 字段的值并将它们放在一起并换行。此外,每个实例都应根据 [hci] 编号(与 HCI 事件在同一行)放入特定文件中。例如,从 hci 0 的每个 HCI 事件(满足描述的条件),它都会转到文件-hci0.txt,从 hci1 到 file-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)

脚本文件:

 == ">" {
          cnt++
          for (i=1;i<=NF;i++) {
                if ( $i ~ /\[.*\]/ ) {
                                 hci[cnt]=substr($i,2,length($i)-2)
                        }
                }
        }
 == "Address:" {
           add[cnt]=
        }
[=10=] ~ /32f9169f-4feb-4883-ade6-1f0127018db3/ {
           fnd[cnt]=""
        }
 == "RSSI:"   {
           str=substr(,length()-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。然后,我们遍历该行的每个字段,并根据以 [] 开头和以 ] 结尾的任何内容进行检查。然后,此文本使用 substr 删除了 [ 和 ],并添加到使用 cnt 索引的数组 hci 中。然后我们将所有地址存储在数组 add 中,并将 RSSI 文本(使用 substr 和 gsub 格式化)存储在 rssi 中。如果 mac 地址匹配,则创建数组 fnd。所有数组都由 cnt 索引。我们最终循环遍历 fnd 并从其他数组中提取其他数据,打印所需的输出并重定向以创建所需的文件。

在 Ruby、awk、Python、Perl 中你可以:

  1. 将文本分成块;
  2. 针对您描述的三个正则表达式测试每个块;
  3. 解析块;
  4. 打印到适当的文件。

第一部分是通过使用sed在块之间添加一个\n来辅助的,然后使用awk来处理每个块。这里 sedawk 正在生成感兴趣的块(其中 2 个):

$ sed 's/^>/\
&/' file | 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