Am analizat alte răspunsuri, dar nu am putut obține o explicație corectă despre cum să faceți acest lucru.
I au o variabilă de șir numită id
astfel încât id="{"name":"john"}"
. Cum pot obține 2 variabile din acest șir ca-
key="name" value="john"
O explicație detaliată ar fi apreciată deoarece vreau să înțeleg analiza șirurilor în bash.
Până acum, am „eliminat parantezele {}
din șirul de caractere-
id="$( echo "${id}" | tr -d {} )"
Nu pot” include "
acolo ca generează o eroare. De asemenea, căutați ceva de genul id.split(":")
în cele din urmă pentru a obține o matrice.
Comentarii
Răspuns
Utilizarea jq
:
id="{"name":"john"}" key=$(jq -r keys[] <<<"$id") value=$(jq -r .[] <<<"$id")
-r
: Cu această opțiune, dacă filtrul „s rezultatul este un șir, apoi va fi scris direct la ieșirea standard, mai degrabă decât formatat ca un șir JSON cu ghilimele.
keys
: Tastele funcționale încorporate, când dat unui obiect, își returnează cheile într-o matrice.
Utilizând json
:
id="{"name":"john"}" key=$(json -ak <<<"$id") value=$(json -a "$key" <<<"$id")
-a
procesează intrarea ca matrice
-k
returnează valorile cheie
Comentarii
- vă mulțumesc pentru explicație. Funcționează excelent. Cred că nu există ‘ că nu există nicio modalitate de a analiza un șir fără
jq
în scripturile bash. - @kev: Există o mulțime de moduri de a analiza șirurile, dar este ‘ un fel de nedrept pentru a numi asta un șir și nu date JSON.
- @kev Datele JSON pot fi codate. Pentru a-l analiza, ar trebui să-l decodezi. De asemenea, JSON nu-i pasă de spațiile albe (linii noi etc.) între taste și valori, așa că ar trebui să țineți cont de asta. Acest lucru a fost făcut deja pentru dvs. de către autorii analizorului JSON subiacent din
jq
.
Răspuns
Ați cerut literalmente să understand string parsing in bash
așa că voi scrie un răspuns având în vedere acest lucru, chiar dacă este soluție greșită pentru problema dvs. . Puteți folosi bash în sine pentru a face ceea ce doriți, dacă aveți cu adevărat curat date fără caractere speciale, în care special este definit ca orice în afara [A-Za-z0-9 ]
:
$name":"john"}" $ # remove everything through the first "{" $ echo $id "name":"john"} $ # remove everything starting with the last "}" $ echo $id "name":"john" $ name="${id%:*}" # take everything before the ":" $ name="${name//\"/}" # remove quotes $ echo $name name $ value="${id#*:}" # take everything after the ":" $ value="${value//\"/}" # remove quotes $ echo $value john
Toate acestea sunt descrise în „Extinderea parametrilor” în manual bash . De exemplu, ${parameter#word}
care va Remove matching prefix pattern
va elimina textul word
de la începutul lui $parameter
. În mod similar, %
elimină sufixul. //
înlocuiește toate aparițiile unui șir cu orice vine după el (în exemplul ${foo//\"/}
de mai sus, ghilimele (care trebuie să fie evitate, deci apar ca \"
) sunt înlocuite cu șirul gol). Totuși, trebuie să efectuați fiecare înlocuire de la sine: nu puteți „elimina începutul și sfârșitul șirului cu o singură comandă.
De asemenea, ați observat probabil trebuie să scape de caractere speciale, cum ar fi }
, {
și "
. Atâta timp cât vă amintiți să faceți acest lucru corect, puteți scrie codul astfel destul de ușor, dar, oricât de simplu este, este în tendință să fie cod numai pentru scriere. Când reveniți cod într-un an sau doi pentru a-l reutiliza, veți privi ceva de genul #*\{}
și vă veți gândi, WTF înseamnă chiar asta? și apoi doar copiați-l orbește într-un proiect nou și apoi codul dvs. se va sparge într-un mod subtil, deoarece întâlnește caractere speciale pe care nu vă așteptați.
Exemplele de mai sus se vor sparge dacă perechile dvs. nume-valoare au caractere speciale în ele, cum ar fi paranteze sau ghilimele sau două puncte sau probabil alte caractere. Deci, acest lucru va funcționa bine pentru o răzuire rapidă și murdară sau pentru cazul de utilizare de 80%, dar nu ar trebui să-l folosiți în producție sau în orice moment trebuie să vă asigurați că funcționează întotdeauna cu orice intrare.
Chiar și fără declarațiile echo
de acolo pentru a vă arăta ce se întâmplă, puteți vedea că acest cod este deja mai lung decât exemplele din celălalt răspuns care arată cum să o faceți corect. Deci, dacă nu utilizați un instrument terță parte, vă „dați mai mult cod pentru a scrie, ceea ce vă va duce mai mult la scriere și depanare, și veți de asemenea să ajungeți la o soluție care este mai puțin flexibilă și care va pauză când întâmpină ceva neașteptat.
Comentarii
- acest lucru a fost destul de informativ – poate ‘ nu înțelegeți de ce oamenii ar vota negativ
Răspuns
Alternativ, puteți utiliza un unix bazat pe o cale de mers pe jos utilitar jtc
:
id="{"name":"john"}" bash $ key=$(jtc -w"[0]<>k" <<<"$id") bash $ echo $key "name" bash $ value=$(jtc -w"[0]" <<<"$id") bash $ echo $value "john" bash $
PS> Divulgare: sunt „creatorul instrumentului jtc
– instrumentul shell cli pentru operațiuni JSON
jq
este folosit de alții, dar nu există nicio modalitate de a putea analiza acest lucru fără un terț instrument?awk
,sed
șigrep
sunt, de asemenea, instrumente terță parte. Dacă utilizați datejson
, nu există absolut niciun motiv să nu aveți instrumentele adecvate pentru a lucra cu acestea.