Analizza una stringa nello script bash

Ho esaminato altre risposte ma non sono riuscito a ottenere una spiegazione adeguata di come farlo.

I avere una variabile stringa chiamata id tale che id="{"name":"john"}". Come posso ottenere 2 variabili da questa stringa come-

key="name" value="john" 

Una spiegazione dettagliata sarebbe apprezzata in quanto voglio comprendere lanalisi delle stringhe in bash.

Finora, ho rimosso le parentesi graffe {} dalla stringa –

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

Non posso” t includere " come genera un errore. Cerca anche qualcosa come id.split(":") alla fine per ottenere un array.

Commenti

  • Possiamo avvisarti di questa tattica / traccia prima che ‘ sia troppo tardi? Sembra che tu abbia json o altri dati strutturati; forse uno strumento dedicato sarebbe un modo più sicuro per portarti dove sei stai andando?
  • Ho visto che jq è utilizzato da altri, ma non posso in alcun modo analizzarlo senza una terza parte strumento?
  • Stai importando questi dati da un file? Potrebbe esserci più di una coppia di chiave / valori? Che aspetto avrebbe una virgoletta doppia come parte del valore?
  • @kev: tecnicamente awk, sed e grep sono anchessi strumenti di terze parti. Se stai utilizzando json dati non cè assolutamente alcun motivo per non disporre degli strumenti adeguati per lavorarci.
  • Questi dati sono il risultato di un comando che ho eseguito nel mio script. Sarà sempre in questo formato: 1 chiave e 1 valore.

Risposta

Utilizzo di jq:

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

-r: con questa opzione, se il filtro “s il risultato è una stringa, quindi verrà scritto direttamente nelloutput standard anziché essere formattato come una stringa JSON tra virgolette.

keys: i tasti funzione incorporati, quando dato un oggetto, restituisce le sue chiavi in un array.


Utilizzando json:

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

-a elabora linput come un array

-k restituisce valori chiave

Commenti

  • grazie per la spiegazione. Funziona benissimo. Ritengo che ‘ non sia possibile analizzare una stringa senza jq negli script bash.
  • @kev: ci sono molti modi per analizzare le stringhe ma ‘ è un po ingiusto per chiamarla stringa e non dati json.
  • I dati JSON @kev possono essere codificati. Per analizzarlo, dovresti potenzialmente decodificarlo. Inoltre, JSON non si preoccupa degli spazi (newline, ecc.) Tra chiavi e valori, quindi dovresti tenerne conto. Questo è già stato fatto per te dagli autori del parser JSON sottostante in jq.

Risposta

Hai letteralmente chiesto di understand string parsing in bash, quindi scriverò una risposta con questo in mente, anche se è soluzione sbagliata per il tuo problema . Puoi usare bash stesso per fare quello che vuoi, se hai veramente pulito dati senza caratteri speciali, dove speciale è definito come qualsiasi cosa al di fuori di [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 

Tutto questo è descritto in “Parameter Expansion” nel manuale di bash . Ad esempio, ${parameter#word} che Remove matching prefix pattern rimuoverà il testo word dallinizio di $parameter. Allo stesso modo, % rimuove il suffisso. // sostituisce tutte le occorrenze di una stringa con ciò che viene dopo (nellesempio ${foo//\"/} sopra, virgolette (che devono essere precedute da caratteri di escape appaiono come \") vengono sostituiti con una stringa vuota). Tuttavia, devi eseguire ogni sostituzione da solo: non puoi rimuovere linizio e la fine della stringa con un comando.

Probabilmente hai anche notato che hai è necessario eseguire lescape di caratteri speciali, come }, { e ". Finché ti ricordi di farlo correttamente, puoi scrivere codice come questo abbastanza facilmente ma, per quanto semplice, tende ad essere codice di sola scrittura. Quando torni a questo codice in un anno o due per riutilizzarlo, guarderai qualcosa come #*\{} e penserai a te stesso, WTF significa? e quindi copiarlo alla cieca in un nuovo progetto e quindi il codice verrà interrotto in modo sottile perché incontra caratteri speciali che non ti aspettavi.

Gli esempi precedenti non funzioneranno se le tue coppie nome-valore contengono caratteri speciali, come parentesi graffe o virgolette o due punti o probabilmente altri caratteri. Quindi questo funzionerà bene per un raschiamento veloce e sporco o per il caso duso dell80%, ma non dovresti usarlo in produzione o ogni volta che devi assicurarti che funzioni sempre con qualsiasi input.

Anche senza le istruzioni echo per mostrarti cosa sta succedendo, puoi vedere che questo codice è già più lungo degli esempi nellaltra risposta che mostrano come farlo propriamente. Quindi, non utilizzando uno strumento di terze parti, ti stai dando più codice da scrivere, il che richiederà più tempo sia per la scrittura che per il debug, e ti ritroverai anche con una soluzione meno flessibile e che lo farà si interrompe quando incontra qualcosa di inaspettato.

Commenti

  • questo è stato abbastanza informativo – può ‘ t capire perché le persone dovrebbero votare in difetto

Answer

In alternativa, potresti usare un unix basato sul percorso utilità 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> Divulgazione: sono il creatore dello jtc – shell cli tool per operazioni JSON

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *