nmcliコマンドの出力(コロンで区切られた値)を処理しようとしていますが、MACまたはBSSIDからエスケープされたコロンを処理/無視することはできません。 awk、jq、sed、regexを試しましたが、私は理解していません...
パイプラインコマンド:
nmcli -f SSID,BSSID,CHAN,FREQ,SIGNAL,SECURITY -t dev wifi
出力例:
WiFi:00\:0A\:97\:6F\:7B\:AC:165:5660 MHz:15:
BSSIDを行/フィールドリストの最後に移動し、最後のフィールドだけを切り捨てるとうまくいきますが、今は誇りに思うでしょう。助けてください!
私は本当に良いことをしているこの既存のスタックオーバーフロースレッドを見つけましたが、最終的に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