Parse en streng i bash-script

Jeg gennemgik andre svar, men kunne ikke få en ordentlig forklaring på, hvordan man gør dette.

I har en strengvariabel kaldet id sådan at id="{"name":"john"}". Hvordan kan jeg få 2 variabler ud af denne streng som-

key="name" value="john" 

En detaljeret forklaring vil blive værdsat, da jeg vil forstå strengparsering i bash.

Indtil videre har jeg fjernet seler {} fra strengen-

id="$( echo "${id}" | tr -d {} )" 

Jeg kan ikke inkludere " derinde som det kaster en fejl. Også på udkig efter noget som id.split(":") til sidst for at få en matrix.

Kommentarer

  • Kan vi advare dig om denne taktik / spor, før det ' er for sent? Det ser ud til, at du har json eller andre strukturerede data der, måske vil et dedikeret værktøj være en sikrere måde at få dig, hvor du går igen?
  • Jeg så, at jq bruges af andre, men er der ingen måde, jeg kan analysere dette uden en tredjepart værktøj?
  • Bringer du disse data ind fra en fil? Kunne der være mere end et par nøgler / værdier? Hvordan ser et dobbelt citat ud som en del af værdien?
  • @kev: Teknisk awk, sed , og grep er også tredjepartsværktøjer. Hvis du bruger json data, er der absolut ingen grund til ikke at have de rette værktøjer til at arbejde med dem.
  • Disse data er resultatet af en kommando, som jeg udført i mit script. Det vil altid være i dette format – 1 nøgle og 1 værdi.

Svar

Brug af jq:

id="{"name":"john"}" key=$(jq -r keys[] <<<"$id") value=$(jq -r .[] <<<"$id") 

-r: Med denne mulighed, hvis filteret “s resultatet er en streng, så skrives den direkte til standardoutput snarere end at blive formateret som en JSON-streng med anførselstegn.

keys: De indbyggede funktionstaster, når givet et objekt, returnerer dets nøgler i en matrix.


Brug json:

id="{"name":"john"}" key=$(json -ak <<<"$id") value=$(json -a "$key" <<<"$id") 

-a behandler input som en matrix

-k returnerer nøgleværdier

Kommentarer

  • tak for forklaringen. Fungerer godt. Jeg regner med, at der ' ingen måde at analysere en streng uden jq i bash-scripts.
  • @kev: Der er masser af måder at analysere strenge på, men det ' er en slags uretfærdig for at kalde dette en streng og ikke json-data.
  • @kev JSON-data kan kodes. For at analysere det skal du muligvis afkode det. JSON er ligeglad med det hvide mellemrum (nye linjer osv.) Mellem nøgler og værdier, så du bliver nødt til at tage det i betragtning. Dette er allerede gjort for dig af forfatterne af den underliggende JSON-parser i jq.

Svar

Du bad bogstaveligt talt om at understand string parsing in bash så jeg skriver et svar med det i tankerne, selvom det er forkert løsning til dit problem . Du kan bruge bash selv til at gøre, hvad du vil, hvis har du virkelig ren data uden specialtegn, hvor special er defineret som noget uden for [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 

Dette er alt beskrevet i “Parameterudvidelse” i bash manual . For eksempel ${parameter#word} som vil Remove matching prefix pattern fjerner teksten word fra begyndelsen af $parameter. Tilsvarende fjerner % suffikset. // erstatter alle forekomster af en streng med hvad der kommer efter den (i ${foo//\"/} eksemplet ovenfor, anførselstegn (som skal undslippes, så vises som \") erstattes med den tomme streng). Du skal udføre hver udskiftning alene, men du kan ikke fjerne begyndelsen og slutningen af strengen med en kommando.

Du har sandsynligvis også bemærket, at du har brug for at undslippe specialtegn som }, { og ". Så længe du husker at få det rigtigt, kan du skrive kode ret nemt, men så enkelt som det er, er det en tendens til at være skrivekode. Når du kommer tilbage til dette kode om et år eller to for at genbruge den, vil du se på noget som #*\{} og tænke over dig selv, WTF betyder det endda? og så kopier det bare blindt ind i et nyt projekt, så bryder din kode på en subtil måde, fordi den støder på specialtegn, som du ikke havde forventet.

Eksemplerne ovenfor brydes, hvis dine navne-værdipar har specielle tegn i sig, som parenteser eller undslapte anførselstegn eller kolon eller sandsynligvis andre tegn. Så dette fungerer fint til noget hurtigt og snavset skrabning eller 80% brugssagen, men du skal virkelig ikke bruge det til produktion eller når som helst du har brug for for at sikre, at det altid fungerer med ethvert input.

Selv uden echo udsagn derinde for at vise dig, hvad der sker, kan du se, at denne kode allerede er længere end eksemplerne i det andet svar, der viser, hvordan du gør det korrekt. Ved ikke at bruge et tredjepartsværktøj giver du dig selv mere kode at skrive, hvilket tager dig længere tid at både skrive og fejle, og du ender også med en løsning, der er mindre fleksibel, og som vil pause når det støder på noget uventet.

Kommentarer

  • dette var ret informativt – kan ' t forstå, hvorfor folk ville nedstemme

Svar

Alternativt kan du bruge en sti-baseret unix værktøj 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> Oplysning: Jeg er skaberen af jtc – shell cli-værktøj til JSON-operationer

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *