Karaktersorozat elemzése a bash szkriptben

Átnéztem más válaszokat, de nem tudtam megfelelő magyarázatot adni erre.

I van egy id nevű karakterlánc-változója úgy, hogy id="{"name":"john"}". Hogyan hozhatok ki 2 változót ebből a karakterláncból, mint például:

key="name" value="john" 

A részletes magyarázatot örömmel fogadnám, mivel meg akarom érteni a string elemzését a bash-ban.

Eddig “eltávolítottam a zárójeleket {} a karaktersorozatból –

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

Nem vehetek fel " hibát dob. A tömb megszerzéséhez is keres valami olyasmit, hogy id.split(":").

Megjegyzések

  • Figyelmeztethetünk-e erre a taktikára / sávra, mielőtt ' túl késő lenne? Úgy tűnik, hogy van itt json vagy más strukturált adat; esetleg egy dedikált eszköz lenne biztonságosabb módja annak, hogy eljusson oda, ahol megy?
  • Láttam, hogy a jq -t mások használják, de ezt semmiképpen sem tudom elemezni harmadik fél nélkül eszköz?
  • Ezeket az adatokat fájlból hozza be? Lehet egynél több kulcs / érték pár? Hogyan nézne ki a kettős idézet az érték részeként?
  • @kev: Technikailag awk, sed és a grep szintén harmadik fél eszközei. Ha json adatokat használ, akkor semmi sem indokolja, hogy ne rendelkezzenek megfelelő eszközökkel a kezelésükhöz.
  • Ez az adat egy parancs eredménye, amelyet a forgatókönyvemben végrehajtva. Mindig ebben a formátumban lesz – 1 kulcs és 1 érték.

Válasz

A jq:

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

-r: Ezzel az opcióval, ha a szűrő “s” Az eredmény egy karakterlánc, majd közvetlenül a standard kimenetre írja, ahelyett, hogy JSON karakterláncként formázná idézőjelekkel.

keys: A beépített funkcióbillentyűk, amikor adott objektumot, egy tömbben adja vissza a kulcsait.


A json használata:

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

-a tömbként dolgozza fel az inputot

-k adja vissza a kulcsértékeket

Megjegyzések

  • köszönöm a magyarázatot. Remekül működik. Úgy gondolom, hogy ' nincs mód a string elemzésére jq a bash szkriptekben.
  • @kev: A húrok elemzésének rengeteg módja van, de ez ' igazságtalan hogy ezt karakterláncnak, és ne json adatnak nevezzük.
  • @kev A JSON adatok kódolhatók. Elemzéséhez potenciálisan dekódolnia kell. A JSON nem törődik a kulcsok és az értékek közötti szóközzel (új sorok stb.), Ezért ezt figyelembe kell vennie. Ezt az alapul szolgáló JSON-elemző készítői már megtették a jq fájlban.

Válasz

Ön szó szerint azt kérte, hogy understand string parsing in bash, ezért ezt szem előtt tartva írok egy választ, annak ellenére, hogy ez a rossz megoldás a problémádra . Magát a bash-t használhatja arra, amit akar, ha valóban tiszta adatok speciális karakterek nélkül, ahol a speciális a [A-Za-z0-9 ] kívüli dologként van meghatározva:

$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 

Mindezt a bash kézikönyv “Paraméter kibővítése” című részében írják le. Például ${parameter#word} amely Remove matching prefix pattern eltávolítja a word szöveget $parameter. Hasonlóképpen a % eltávolítja az utótagot. A // egy sztring minden előfordulását lecseréli bármire, ami utána következik (a fenti ${foo//\"/} példában idézőjelek (amelyeket meg kell kerülni, jelenik meg, mivel \") helyére az üres karakterlánc kerül. Az egyes helyettesítéseket azonban önmagában kell végrehajtania: nem lehet egy paranccsal levetkőzni a karakterlánc elejét és a végét.

Valószínűleg azt is észrevette, hogy el kell kerülnie a speciális karaktereket, például }, { és ". Mindaddig, amíg emlékszik, hogy megkapja ezt a jogot, nagyon könnyen írhat ilyen kódot, de bármennyire egyszerű is, csak írási kód felé fordul. Ha erre visszatér, kódot egy-két év múlva, hogy újra felhasználhassa, akkor valami olyasmit fog megnézni, hogy #*\{}, és gondolja magában: WTF ez egyáltalán azt jelenti? és akkor csak vakon másold át egy új projektbe, és akkor a kódod finom módon el fog törni, mert olyan különleges karakterekkel találkozik, amelyekre nem számítottál.

A fenti példák megszakadnak, ha a név-érték párokban vannak speciális karakterek, például zárójelek, elkerült idézőjelek vagy kettőspontok, vagy valószínűleg más karakterek. Tehát ez jól fog működni néhány gyors és piszkos kaparás vagy a 80% -os felhasználási eset esetén, de valójában nem szabad használni a gyártásban, vagy bármikor meg kell győződnie arról, hogy mindig működik-e bármilyen bemenettel.

A echo utasítások nélkül is, amelyek megmutatják, mi történik, láthatja, hogy ez a kód már hosszabb, mint a másik válaszban szereplő példák, amelyek megmutatják, hogyan kell csinálni megfelelően. Tehát azzal, hogy nem használ harmadik féltől származó eszközt, több kódot ad magának az írásra, ami hosszabb időt vesz igénybe mind az írás, mind a hibakeresés során, és egy kevésbé rugalmas megoldással is végződik, amely törés, ha valami váratlan dologgal találkozik.

Megjegyzések

  • ez meglehetősen informatív volt – tud ' nem érti, miért szavaznának le az emberek

Válasz

Alternatív megoldásként használhat sétányon alapuló unix segédprogram 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> Közzététel: Én vagyok a jtc – shell cli eszköz készítője JSON műveletekhez

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük