analisa pares de valores separados por dois pontos, com caracteres de dois-pontos escapados no (s) campo (s)

1

Estou tentando processar a saída do comando nmcli (valores separados por dois pontos), mas não consigo manipular / ignorar dois-pontos com escape no MAC ou no BSSID. Eu tentei awk, jq, sed, regex, mas simplesmente não entendi ...

comando canalizado:

nmcli -f SSID,BSSID,CHAN,FREQ,SIGNAL,SECURITY -t dev wifi
Exemplo de saída

:

WiFi:00\:0A\:97\:6F\:7B\:AC:165:5660 MHz:15:

Se eu mover o BSSID para o final da lista da linha / campo (e depois cortar o último campo) ele funcionará, mas agora é uma questão de orgulho. Por favor ajude!

Eu encontrei este thread stackoverflow existente, o que realmente aconteceu muito bem, mas estou ultimamente encontrando o mesmo problema de como ignorar os dois-pontos escapados no endereço MAC! @% $: pares de valores separados por dois pontos

Tentativa mais recente (legível):

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]})'

e saída do problema:

...
{
"SSID": "WiFi",
"BSSID": "00\",
"CHAN": "0A\",
"RATE": "97\",
"FREQ": "6F\",
"SIGNAL": "7B\",
"SECURITY": "AC"
},
...

Também precisaria que o JQ deixasse o cólon no lugar e não escapasse como mostrado acima, se possível, ... por favor não diga apenas python ...

    
por Lord Vance 21.03.2018 / 01:12

4 respostas

3

Algumas notas aqui:

  • Você pode impedir que nmcli escape dos campos com --escape/-e no
  • Você não precisa citar os nomes dos campos json (sem caracteres especiais)
  • SSID e Security nem sempre são retornados, então adicionei um marcador de posição ( -- )

    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)})'
    
por 12.04.2018 / 06:53
2

O Perl permite que você construa um separador de campo com lookbehind - e também oferece um módulo JSON JSON . Então você poderia fazer algo como

nmcli -f SSID,BSSID,CHAN,FREQ,SIGNAL,SECURITY -t dev wifi | 
  perl -F'(?<!\):' -MJSON=encode_json -lne 'print encode_json([map { s/\:/:/g ; $_ } @F])'

Teste com seu exemplo nmcli output:

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"]
    
por 21.03.2018 / 01:55
1

O GNU awk pode manipular campos como sequências de caracteres com escape ou caracteres sem cólon-nem-barra invertida (veja esta resposta ), então o seguinte deve funcionar. Não é muito eficiente, mas pelo menos uma solução ...

#!/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
    
por 21.03.2018 / 01:42
1

Usando sed para limpar os dados e mlr para transformá-lo em JSON:

h='SSID,BSSID,CHAN,FREQ,SIGNAL,SECURITY'
nmcli -f $h -t dev wifi | 
sed 's/^:/"",/;s/\([^\]\):/,/g;s/[\]:/:/g' | 
mlr --c2j --jvstack  --jlistwrap  label $h

Exemplo de saída:

{
  "SSID": "FooBarBaz",
  "BSSID": "13:F6:8C:56:9B:3B",
  "CHAN": 36,
  "FREQ": "5180 MHz",
  "SIGNAL": 20,
  "SECURITY": "WPA1 WPA2"
},
    
por 23.04.2018 / 06:46