在某些特定条件下通过 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 中你可以:
- 将文本分成块;
- 针对您描述的三个正则表达式测试每个块;
- 解析块;
- 打印到适当的文件。
第一部分是通过使用sed
在块之间添加一个\n
来辅助的,然后使用awk
来处理每个块。这里 sed
和 awk
正在生成感兴趣的块(其中 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
我有一个输出(一个众所周知的 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 中你可以:
- 将文本分成块;
- 针对您描述的三个正则表达式测试每个块;
- 解析块;
- 打印到适当的文件。
第一部分是通过使用sed
在块之间添加一个\n
来辅助的,然后使用awk
来处理每个块。这里 sed
和 awk
正在生成感兴趣的块(其中 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