Jag granskade andra svar men kunde inte få en ordentlig förklaring till hur man gör det.
I har en strängvariabel som heter id
så att id="{"name":"john"}"
. Hur kan jag få 2 variabler ur denna sträng som-
key="name" value="john"
En detaljerad förklaring skulle uppskattas eftersom jag vill förstå strängparsning i bash.
Hittills har jag tagit bort hängslen {}
från strängen-
id="$( echo "${id}" | tr -d {} )"
Jag kan inte inkludera "
där inne som det kastar ett fel. Letar också efter något som id.split(":")
i slutändan för att få en matris.
Kommentarer
Svar
Använd jq
:
id="{"name":"john"}" key=$(jq -r keys[] <<<"$id") value=$(jq -r .[] <<<"$id")
-r
: Med detta alternativ, om filtret ”s resultatet är en sträng, då kommer den att skrivas direkt till standardutdata istället för att formateras som en JSON-sträng med citat.
keys
: De inbyggda funktionstangenterna, när ges ett objekt, returnerar dess nycklar i en matris.
Med json
:
id="{"name":"john"}" key=$(json -ak <<<"$id") value=$(json -a "$key" <<<"$id")
-a
bearbetar inmatning som en array
-k
returnerar nyckelvärden
Kommentarer
- tack för förklaringen. Fungerar bra. Jag tror att ' inte kan analysera en sträng utan
jq
i bash-skript. - @kev: Det finns många sätt att analysera strängar men det ' är typ av orättvist för att kalla detta en sträng och inte json-data.
- @kev JSON-data kan kodas. För att analysera det skulle du eventuellt behöva avkoda det. Dessutom bryr sig JSON inte om mellanslag (nylinjer etc.) mellan nycklar och värden, så du måste ta hänsyn till det. Detta har redan gjorts åt dig av författarna till den underliggande JSON-analysatorn i
jq
.
Svar
Du bad bokstavligen understand string parsing in bash
så jag skriver ett svar med det i åtanke, även om det är fel lösning på ditt problem . Du kan använda bash själv för att göra vad du vill, om har du riktigt ren data utan specialtecken, där special definieras som något utanför [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
Allt detta beskrivs i ”Parameter Expansion” i bash manual . Till exempel ${parameter#word}
som kommer att Remove matching prefix pattern
tar bort texten word
från början av $parameter
. På samma sätt tar %
bort suffixet. //
ersätter alla förekomster av en sträng med vad som kommer efter den (i ${foo//\"/}
exempel ovan, citat (som måste undvikas, så visas som \"
) ersätts med den tomma strängen). Du måste dock utföra varje byte av sig själv: du kan inte ta bort början och slutet av strängen med ett kommando.
Du har antagligen också märkt att du måste undkomma specialtecken, som }
, {
och "
. Så länge du kommer ihåg att få rätt, kan du skriva kod så här ganska enkelt, men så enkelt som det är, trender det mot att vara enbart skrivkod. När du kommer tillbaka till detta kod om ett år eller två för att återanvända den, kommer du att titta på något som #*\{}
och tänka för dig själv, WTF betyder det ens? och sedan bara kopiera den blindt till ett nytt projekt och sedan kommer din kod att brytas på ett subtilt sätt eftersom den stöter på specialtecken som du inte förväntade dig.
Exemplen ovan kommer att brytas om dina namn-värde-par har specialtecken i sig, som parenteser eller undantagna citat eller kolon eller förmodligen andra tecken. Så det kommer att fungera bra för snabb och smutsig skrapning eller 80% användningsfall, men du borde verkligen inte använda det i produktionen eller när som helst du behöver för att se till att det alltid fungerar med någon ingång.
Även utan echo
uttalanden där inne för att visa vad som händer kan du se att den här koden redan är längre än exemplen i det andra svaret som visar hur du gör det ordentligt. Genom att inte använda ett tredjepartsverktyg ger du dig själv mer kod att skriva, vilket tar dig längre tid att både skriva och felsöka, och du slutar också med en lösning som är mindre flexibel och som kommer att paus när det stöter på något oväntat.
Kommentarer
- det var ganska informativt – kan ' t förstå varför folk skulle rösta ned
Svar
Alternativt kan du använda en gångbaserad unix verktyg 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> Upplysning: Jag är skaparen av jtc
– shell cli-verktyget för JSON-operationer
jq
används av andra, men kan jag inte analysera detta utan en tredje part verktyg?awk
,sed
, ochgrep
är också verktyg från tredje part. Om du använderjson
data finns det absolut ingen anledning att inte ha rätt verktyg för att arbeta med dem.