我正在尝试处理 nmcli 命令的输出(冒号分隔值),但无法处理/忽略 MAC 或 BSSID 中的转义冒号。我尝试过 awk、jq、sed、正则表达式,但就是不明白......
管道命令:
nmcli -f SSID,BSSID,CHAN,FREQ,SIGNAL,SECURITY -t dev wifi
示例输出:
WiFi:00\:0A\:97\:6F\:7B\:AC:165:5660 MHz:15:
如果我将 BSSID 移动到行/字段列表的末尾(然后只剪切最后一个字段),它就会起作用,但现在这是一个值得骄傲的事情。请帮忙!
我确实找到了这个现有的 stackoverflow 线程,它确实做得很好,但我最终遇到了同样的问题,即如何忽略 MAC!@%$ 地址中的转义冒号: 解析冒号分隔的值对
最近的(可读的)尝试:
printf '%s' "$(nmcli -f SSID,BSSID,CHAN,FREQ,SIGNAL,SECURITY -t dev wifi)" | jq -sR 'split("\n") | map(split(":")) | map({"SSID": .[0], "BSSID": .[1], "CHAN": .[2], "RATE": .[3], "FREQ": .[4], "SIGNAL": .[5], "SECURITY": .[6]})'
和问题输出:
...
{
"SSID": "WiFi",
"BSSID": "00\\",
"CHAN": "0A\\",
"RATE": "97\\",
"FREQ": "6F\\",
"SIGNAL": "7B\\",
"SECURITY": "AC"
},
...
还需要 JQ 将冒号保留在适当的位置,而不是如上所示转义,如果可能的话,...请不要只说 python...
答案1
这里有一些注意事项:
- 您可以
nmcli
通过以下方式防止转义字段--escape/-e no
- 您不必引用 json 字段名称(不含特殊字符)
SSID
并且Security
并不总是返回,所以我添加了一个占位符 (--
)printf '%s' "$(nmcli -f SSID,BSSID,CHAN,FREQ,SIGNAL,SECURITY -e no -t dev wifi)" | jq -sR 'split("\n") | map(split(":") | {SSID: (if .[0] == "" then "--" else .[0] end), BSSID: .[1:6] | join(":"), CHAN: .[7], FREQ: .[8], SIGNAL: .[9], SECURITY: (if .[10] == "" then "--" else .[10] end)})'
答案2
Perl 允许您使用 Lookbehind 构造字段分隔符 - 并且还可以轻松地提供JSON模块。所以你可以做类似的事情
nmcli -f SSID,BSSID,CHAN,FREQ,SIGNAL,SECURITY -t dev wifi |
perl -F'(?<!\\):' -MJSON=encode_json -lne 'print encode_json([map { s/\\:/:/g ; $_ } @F])'
使用示例nmcli
输出进行测试:
printf 'WiFi:00\:0A\:97\:6F\:7B\:AC:165:5660 MHz:15:' |
perl -F'(?<!\\):' -MJSON=encode_json -lne 'print encode_json([map { s/\\:/:/g ; $_ } @F])'
["WiFi","00:0A:97:6F:7B:AC","165","5660 MHz","15"]
答案3
用于sed
清理数据,以及mlr
将其转换为 JSON:
h='SSID,BSSID,CHAN,FREQ,SIGNAL,SECURITY'
nmcli -f $h -t dev wifi |
sed 's/^:/"",/;s/\([^\]\):/\1,/g;s/[\]:/:/g' |
mlr --c2j --jvstack --jlistwrap label $h
输出示例:
{
"SSID": "FooBarBaz",
"BSSID": "13:F6:8C:56:9B:3B",
"CHAN": 36,
"FREQ": "5180 MHz",
"SIGNAL": 20,
"SECURITY": "WPA1 WPA2"
},
答案4
GNU awk 可以将字段处理为转义字符或非冒号或反斜杠字符的序列(请参阅这个答案),所以以下应该有效。不是很有效,但至少是一个解决方案......
#!/bin/bash
line="WiFi:00\:0A\:97\:6F\:7B\:AC:165:5660 MHz:15:"
# line=`nmcli -f SSID,BSSID,CHAN,FREQ,SIGNAL,SECURITY -t dev wifi`
for i in 1 2 3 4 5; do
echo $line | gawk -v FPAT='(\\\\.|[^\\\\:])*' '{print $'$i'}'
done