나는 썼다스크립트출력을
nmcli --mode multiline dev wifi
JSON으로 변환했지만 일관성이 없습니다.(결과에 공백이 있으면 중단됨), 길고 읽기 어렵습니다.
결과를 직접 jq
.
출력 nmcli
(내 스크립트에 대한 입력)은 다음과 같습니다.
*:
SSID: VIDEOTRON2255
MODE: Infra
CHAN: 11
RATE: 54 Mbit/s
SIGNAL: 69
BARS: ▂▄▆_
SECURITY: WPA1 WPA2
*: *
SSID: VIDEOTRON2947
MODE: Infra
CHAN: 6
RATE: 54 Mbit/s
SIGNAL: 49
BARS: ▂▄__
SECURITY: WPA1 WPA2
다음과 같은 것을 생성하고 싶습니다.
[{
"network": "VIDEOTRON2255",
"mode": "Infra",
"chan": "11",
"rate": "54 Mbit/s",
"signal": "69",
"bars": "▂▄▆_",
"security": "WPA1 WPA2"
},
{
"network": "VIDEOTRON2947",
"mode": "Infra",
"chan": "6",
"rate": "54 Mbit/s",
"signal": "49",
"bars": "▂▄__",
"security": "WPA1 WPA2"
}]
나는 물었다관련 질문더 일찍. 이것은첫 번째 스크립트바탕으로 썼어요자일스의 대답. 일부 값에서는 작동하지만 security
공백 에서는 작동하지 않습니다 rate
.
답변1
당신이 연결한 스크립트는 매우 비효율적입니다. 사용된 모드에서... 쓸모없는 전처리를 많이 하고 있습니다.
왜냐하면 매뉴얼에 따르면,nmcli
--terse
"이 모드는 컴퓨터(스크립트) 처리를 위해 설계되었습니다.", 필수 필드를 지정하고 출력을 jq -sR
예 를 들어 파이프하십시오.
printf '%s' "$(nmcli -f ssid,mode,chan,rate,signal,bars,security -t dev wifi)" | \
jq -sR 'split("\n") | map(split(":")) | map({"network": .[0],
"mode": .[1],
"channel": .[2],
"rate": .[3],
"signal": .[4],
"bars": .[5],
"security": .[6]})'
답변2
이것암소 비슷한 일종의 영양 sed
코드는 아니지만 jq
(복잡한 변환은 아님) 충분히 잘 작동하는 것 같습니다.술집나오면 괜찮을 것입니다) :
nmcli --mode multiline dev wifi |
sed '/^*/! {s/^[A-Z]*/\L&/
s/ssid/network/
s/: */": "/
s/$/"/
{/^sec/!s/$/,/}
s/^/\t"/}
1 s/^\*.*/[{/
/^\*/ s/.*/},\n{/
$ {p;s/.*/}]/}'
독립형 스크립트를 더 쉽게 읽을 수 있습니다 pcsvp.sed
(파일에 저장한 후 실행 chmod +x pcsvp.sed
).
#!/bin/sed -f
# Text lines (the non "*:" lines.)
/^*/! {s/^[A-Z]*/\L&/
s/ssid/network/
s/: */": "/
s/$/"/
{/^sec/!s/$/,/}
s/^/\t"/}
# First JSON line
1 s/^\*.*/[{/
# Middle JSON lines. If a line begins with a '*'...
/^\*/ s/.*/},\n{/
# Last line, close up the JSON.
$ {p;s/.*/}]/}
실행하려면 다음을 수행하십시오.
nmcli --mode multiline dev wifi | ./pcsvp.sed
참고:입력 파일에 관한 질문, 대신 입력을 사용하기로 결정했습니다 nmcli
. 내 위치에서는 약 50개의 네트워크가 표시되므로 여기서 인용하기에는 결과 출력이 너무 길어집니다.
입력 샘플 철자 오류가 수정되면 ./pcsvp.sed input.txt
출력은 다음과 같습니다.
[{
"network": "VIDEOTRON2255",
"mode": "Infra",
"chan": "11",
"rate": "54 Mbit/s",
"signal": "69",
"bars": "▂▄▆_",
"security": "WPA1 WPA2"
},
{
"network": "VIDEOTRON2947",
"mode": "Infra",
"chan": "6",
"rate": "54 Mbit/s",
"signal": "49",
"bars": "▂▄__",
"security": "WEP"
}]
답변3
복잡한jq
해결책( BARS
불규칙/비ASCII 문자가 포함되어 있으므로 줄을 제거하십시오):
입력 파일 input.txt
:
*:
SSID: VIDEOTRON2255
MODE: Infra
CHAN: 11
RATE: 54 Mbit/s
SIGNAL: 69
SECURITY: WPA1 WPA2
*: *
SSID: VIDEOTRON2947
MODE: Infra
CHAN: 6
RATE: 54 Mbit/s
SIGNAL: 49
SECURITY: WPA1 WPA2
일하다:
jq -sR '[ gsub("[*]: *\n| {2,}";"") | gsub("SSID";"network") | split("\n[*]:[*] +\n";"n")[]
| [ capture("(?<key>[^:\n]+):(?<value>[^:\n]+)";"g") | .key |= (. | ascii_downcase) ]
| from_entries ]' input.txt
산출:
[
{
"network": "VIDEOTRON2255",
"mode": "Infra",
"chan": "11",
"rate": "54 Mbit/s",
"signal": "69",
"security": "WPA1 WPA2"
},
{
"network": "VIDEOTRON2947",
"mode": "Infra",
"chan": "6",
"rate": "54 Mbit/s",
"signal": "49",
"security": "WPA1 WPA2"
}
]
다른 특정 입력을 올리거나 게시하는 추가 방법https://pastebin.com/8stHSUeu:
jq -sR '[sub("[*]: *[*]\n";"") | gsub(" {2,}";"") | gsub("SSID";"network")
| split("\n[*]: *\n";"n")[]
| [ capture("(?<key>[^:\n]+):(?<value>[^:\n]+)";"g") | .key |= (. | ascii_downcase) ]
| from_entries]' input.txt
답변4
가능하다면 JSON을 앞뒤로 이해하는 도구를 사용하세요. 저는 Python을 사용하겠습니다.
#! /usr/bin/env python3
import json
import re
import sys
objects = []
obj = {}
for line in sys.stdin:
entry = re.split(':\s*', line.strip(), maxsplit=1) # split on first `:`
if entry[0] == '*':
if obj: # skip a null entry (the first, here)
obj['network'] = obj.pop('ssid') # rename the SSID entry
objects.append(obj)
obj = {} # start a new object for each `*`
continue
obj[entry[0].lower()] = entry[1] # lowercase the key
obj['network'] = obj.pop('ssid') # rename the SSID entry
objects.append(obj)
json.dump(objects, sys.stdout)
이해해 주세요:
[{"mode": "Infra", "chan": "11", "rate": "54 Mbit/s", "signal": "69", "bars": "\u2582\u2584\u2586_", "security": "WPA1 WPA2", "network": "VIDEOTRON2255"}, {"ssid": "VIDEOTRON2947", "mode": "Infra", "chan": "6", "rate": "54 Mbit/s", "signal": "49", "bars": "\u2582\u2584__", "security": "WPA1 WPA2"}]
아름답게 인쇄하면 jq
다음과 같습니다.
[
{
"mode": "Infra",
"chan": "11",
"rate": "54 Mbit/s",
"signal": "69",
"bars": "▂▄▆_",
"security": "WPA1 WPA2",
"network": "VIDEOTRON2255"
},
{
"ssid": "VIDEOTRON2947",
"mode": "Infra",
"chan": "6",
"rate": "54 Mbit/s",
"signal": "49",
"bars": "▂▄__",
"security": "WPA1 WPA2"
}
]