Jai passé en revue dautres réponses mais je nai pas pu obtenir une explication appropriée sur la façon de procéder.
I avoir une variable de chaîne appelée id
telle que id="{"name":"john"}"
. Comment puis-je obtenir 2 variables de cette chaîne comme-
key="name" value="john"
Une explication détaillée serait appréciée car je veux comprendre lanalyse des chaînes dans bash.
Jusquà présent, jai « supprimé les accolades {}
à partir de la chaîne-
id="$( echo "${id}" | tr -d {} )"
Je ne peux » t inclure "
là-dedans comme il renvoie une erreur. Recherche également quelque chose comme id.split(":")
à la fin pour obtenir un tableau.
Commentaires
Réponse
En utilisant jq
:
id="{"name":"john"}" key=$(jq -r keys[] <<<"$id") value=$(jq -r .[] <<<"$id")
-r
: Avec cette option, si le filtre « s result est une chaîne, elle sera écrite directement sur la sortie standard plutôt que dêtre formatée comme une chaîne JSON avec des guillemets.
keys
: Les touches de fonction intégrées, donné un objet, renvoie ses clés dans un tableau.
Utilisation de json
:
id="{"name":"john"}" key=$(json -ak <<<"$id") value=$(json -a "$key" <<<"$id")
-a
traite lentrée sous forme de tableau
-k
renvoie les valeurs clés
Commentaires
- merci pour lexplication. Fonctionne très bien. Je pense que ‘ est impossible danalyser une chaîne sans
jq
dans les scripts bash. - @kev: Il existe de nombreuses façons danalyser des chaînes mais ‘ est plutôt injuste pour appeler cela une chaîne et non des données JSON.
- @kev Les données JSON peuvent être encodées. Pour lanalyser, vous devrez potentiellement le décoder. De plus, JSON ne se soucie pas des espaces (retours à la ligne, etc.) entre les clés et les valeurs, vous devrez donc en tenir compte. Cela a déjà été fait pour vous par les auteurs de lanalyseur JSON sous-jacent dans
jq
.
Réponse
Vous avez littéralement demandé à understand string parsing in bash
donc jécrirai une réponse dans cet esprit, même si cest le mauvaise solution pour votre problème . Vous pouvez utiliser bash lui-même pour faire ce que vous voulez, si vous avez vraiment propre données sans caractères spéciaux, où spécial est défini comme tout ce qui se trouve en dehors de [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
Tout cela est décrit dans « Expansion des paramètres » du manuel bash . Par exemple, ${parameter#word}
qui Remove matching prefix pattern
supprimera le texte word
du début de $parameter
. De même, %
supprime le suffixe. //
remplace toutes les occurrences dune chaîne par ce qui suit (dans lexemple ${foo//\"/}
ci-dessus, des guillemets (qui doivent être échappés, donc apparaissent comme \"
) sont remplacés par la chaîne vide). Cependant, vous devez effectuer chaque substitution par elle-même: vous ne pouvez pas supprimer le début et de la fin de la chaîne avec une seule commande.
Vous avez probablement également remarqué que vous doivent échapper les caractères spéciaux, comme }
, {
et "
. Tant que vous vous souvenez de bien faire les choses, vous pouvez écrire du code comme celui-ci assez facilement mais, aussi simple soit-il, il a tendance à être du code en écriture seule. Quand vous revenez à ceci code dans un an ou deux pour le réutiliser, vous allez regarder quelque chose comme #*\{}
et penser à vous-même, WTF est-ce que cela veut dire? et puis copiez-le aveuglément dans un nouveau projet et votre code se cassera de manière subtile car il rencontre des caractères spéciaux auxquels vous ne vous attendiez pas.
Les exemples ci-dessus ne fonctionneront pas si vos paires nom-valeur contiennent des caractères spéciaux, comme des accolades, des guillemets ou des deux-points ou probablement dautres caractères. Donc, cela fonctionnera bien pour un grattage rapide et sale ou le cas dutilisation à 80%, mais vous ne devriez vraiment pas lutiliser en production ou à tout moment où vous devez vous assurer quil fonctionne toujours avec nimporte quelle entrée.
Même sans les instructions echo
pour vous montrer ce qui se passe, vous pouvez voir que ce code est déjà plus long que les exemples de lautre réponse qui montrent comment le faire correctement. Donc, en nutilisant pas un outil tiers, vous vous donnez plus de code à écrire, ce qui vous prendra plus de temps à écrire et à déboguer, et vous vous retrouvez également avec une solution moins flexible et qui va pause quand il rencontre quelque chose dinattendu.
Commentaires
- cétait assez informatif – peut ‘ t comprendre pourquoi les gens voteraient contre
Réponse
Alternativement, vous pouvez utiliser un Unix basé sur un chemin de marche utilitaire 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> Divulgation: Je « suis le créateur de loutil jtc
– shell cli pour les opérations JSON
jq
est utilisé par dautres, mais je ne peux pas analyser cela sans un tiersawk
,sed
etgrep
sont également des outils tiers. Si vous utilisez des donnéesjson
, il ny a absolument aucune raison de ne pas disposer des outils appropriés pour les utiliser.