Analyzovat řetězec v bash skriptu

Zkontroloval jsem další odpovědi, ale nemohl jsem získat správné vysvětlení, jak to udělat.

I mít řetězcovou proměnnou nazvanou id takovou, aby id="{"name":"john"}". Jak mohu z tohoto řetězce získat 2 proměnné jako –

key="name" value="john" 

Bylo by oceněno podrobné vysvětlení, protože chci porozumět analýze řetězců v bash.

Zatím jsem odstranil závorky {} z řetězce –

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

Nemohu tam zahrnout " vyvolá chybu. Hledá také něco jako id.split(":") a nakonec získá pole.

Komentáře

  • Můžeme vás varovat před touto taktikou / stopou, než bude ' příliš pozdě? Zdá se, že tam máte JSON nebo jiná strukturovaná data; možná by byl vyhrazený nástroj bezpečnější způsob, jak se dostat tam, kam chystáte se?
  • Viděl jsem, že jq používají ostatní, ale neexistuje způsob, jak to mohu analyzovat bez třetí strany nástroj?
  • Přenášíte tato data ze souboru? Může existovat více než jeden pár klíč / hodnota? Jak by vypadala uvozovka jako součást hodnoty?
  • @kev: Technicky awk, sed a grep jsou také nástroje třetích stran. Pokud používáte json data, není absolutně žádný důvod, abyste neměli správné nástroje pro práci s nimi.
  • Tato data jsou výsledkem příkazu, který provedeno v mém skriptu. Vždy bude v tomto formátu – 1 klíč a 1 hodnota.

Odpověď

Použití jq:

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

-r: S touto možností, pokud je filtr result is a string then it will be written directly to standard output rather than being formatted as a JSON string with quotes.

keys: Integrované funkční klávesy, když daný objekt, vrátí jeho klíče v poli.


Pomocí json:

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

-a zpracovává vstup jako pole

-k vrací klíčové hodnoty

Komentáře

  • děkuji za vysvětlení. Funguje skvěle. Myslím, že ' neexistuje způsob, jak analyzovat řetězec bez jq v bash skriptech.
  • @kev: Existuje spousta způsobů, jak analyzovat řetězce, ale ' je to nefér nazývat to řetězcem a ne daty JSON.
  • @kev Data JSON lze kódovat. Chcete-li jej analyzovat, budete jej pravděpodobně muset dekódovat. Také JSON se nestará o mezery (nové řádky atd.) Mezi klíči a hodnotami, takže byste to museli vzít v úvahu. Toto již pro vás provedli autoři podkladového analyzátoru JSON v jq.

Odpovědět

Doslova jste požádali o understand string parsing in bash, abych na to napsal odpověď, i když je to nesprávné řešení vašeho problému . Samotný bash můžete použít k tomu, co chcete, if máte opravdu čistý data bez speciálních znaků, kde speciální je definováno jako cokoli mimo [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 

To vše je popsáno v části „Rozšíření parametrů“ v bash manuálu . Například ${parameter#word}, který Remove matching prefix pattern odstraní text word od začátku $parameter. Podobně % odstraní příponu. // nahradí všechny výskyty řetězce tím, co následuje po něm (ve výše uvedeném příkladu ${foo//\"/} jsou uvozovky (které je třeba uvést jsou zobrazeny jako \") jsou nahrazeny prázdným řetězcem). Každou substituci musíte provést samostatně: jedním začátkem můžete „odříznout začátek a konce řetězce.

Pravděpodobně jste si také všimli, že jste je třeba uniknout speciálním znakům, například }, { a ". Dokud si vzpomenete, že máte toto právo, můžete psát tento kód docela snadno, ale jakkoli je to jednoduché, směřuje k tomu, aby byl kód pouze pro zápis. Když se k tomu vrátíte kód za rok nebo dva, abyste jej mohli znovu použít, podíváte se na něco jako #*\{} a myslíte si: WTF to vůbec znamená? a pak jej jen slepě zkopírujte do nového projektu a váš kód se pak jemným způsobem rozbije, protože narazí na speciální znaky, které jste nečekali.

Výše uvedené příklady se rozpadnou, pokud vaše dvojice název-hodnota obsahuje speciální znaky, například složené závorky nebo uvozovky, dvojtečky nebo pravděpodobně další znaky. Takže to bude fungovat dobře pro nějaké rychlé a špinavé škrábání nebo 80% případ použití, ale opravdu byste jej neměli používat ve výrobě nebo kdykoli potřebujete, abyste se ujistili, že to vždy funguje s jakýmkoli vstupem.

I bez příkazů echo, které by vám ukázaly, co se děje, vidíte, že tento kód je již delší než příklady v jiné odpovědi, které ukazují, jak to udělat správně. Pokud tedy nepoužíváte nástroj třetí strany, dáváte si k psaní více kódu, což vám bude trvat déle, než budete psát i ladit, a také skončíte s méně flexibilním řešením, které rozbije se, když narazí na něco neočekávaného.

Komentáře

  • toto bylo docela informativní – může ' nechápu, proč by lidé hlasovali proti

odpovědi

Případně můžete použít unix založený na pochůzce obslužný program 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> Zveřejnění: Jsem tvůrcem nástroje jtc – shell cli pro operace JSON

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *