J'ai ce texte json:
{
"buildStatus" : {
"status" : "ERROR",
"conditions" : [{
"status" : "OK",
"metricKey" : "bugs"
}, {
"status" : "ERROR",
"metricKey" : "test_success_density"
}, {
"status" : "OK",
"metricKey" : "vulnerabilities"
}
],
"periods" : []
}
}
Je veux extraire l'état général du buildStatus, c'est-à-dire que la sortie attendue était "ERREUR"
"buildStatus" : {
"status" : "ERROR",
....
}
J'ai essayé l'expression sed ci-dessous, mais ça ne marche pas, ça revient OK
:
status= sed -E 's/.*\"buildStatus\":.*\"status\":\"([^\"]*)\",.*/\1/' jsonfile
Qu'est-ce que je fais mal?
la source
jq
:jq -r .buildStatus.status
Emploi pour
jq
:Peut être raccourci à:
-r
(--raw-output
) génère la chaîne sansjson
formatage de chaîne, c'est-à-dire sans guillemets.Exemple:
S'il n'est pas déjà installé, installez-le par (disponible dans le référentiel Universe):
la source
Comme cela a été mentionné, l'analyse des données structurées complexes est préférable avec une API appropriée. Python a un
json
module pour cela, que j'utilise personnellement beaucoup dans mes scripts, et il est assez facile d'extraire les champs souhaités comme vous le souhaitez:Ce qui se passe ici, c'est que nous redirigeons le fichier d'entrée vers stdin de python, et lisons cela avec
json.load()
. Cela devient un dictionnaire python avec la clé "buildStatus", et il contient un autre dictionnaire python avec la clé "status". Ainsi, nous imprimons simplement la valeur d'une clé dans un dictionnaire stocké dans un autre dictionnaire. Assez simple.Mis à part la simplicité, un autre avantage est que python et cette API sont tous préinstallés et livrés avec Ubuntu par défaut.
la source
Vous pouvez réellement le faire dans
sed
, mais je vous invite fortement à utiliser un langage plus sophistiqué qui a des outils écrits pour gérer les données JSON. Vous pouvez essayer perl ou python, par exemple.Maintenant, dans votre exemple simple, tout ce que vous voulez, c'est la première occurrence de
"status"
, vous pouvez donc faire:L'astuce est d'utiliser
-n
pour éviter d'imprimer, puis si la ligne correspond àstatus
(/status/
), vous supprimez tout sauf la partie que vous voulezs/.*:\s*"(.*)",/\1/
,p
imprimez la ligne etq
uit.Personnellement, je trouve cette commande grep équivalente beaucoup plus simple:
Ou celui-ci:
Sérieusement, si vous prévoyez d'analyser des fichiers JSON, n'essayez pas de le faire manuellement. Utilisez un analyseur JSON approprié.
la source
grep -m 1 status file.json | tr -cd '[[:alnum:]]:' | cut -f2 -d':'
Je ne dis pas que vous devriez utiliser
sed
(je pense que quelqu'un m'a déçu juste pour ne pas avoir écrit de mise en garde obligatoire) mais, si vous devez rechercher quelque chose sur la ligne suivantebuildStatus
comme vous semblez essayer dans votre propre tentative, vous devez diresed
à lire la ligne suivante avec laN
commandeRemarques:
-n
n'imprimez rien avant de le demander-r
utiliser ERE (identique à-E
)/buildStatus/N
trouver ce modèle et lire la ligne suivante aussis/old/new/
remplacerold
parnew
.*
un nombre quelconque de caractères sur la ligne\n
nouvelle ligne: "(.*)",
enregistrer tous les caractères apparaissant entre: "
et",
\1
référence arrière au motif enregistrép
imprimer la partie sur laquelle nous avons travailléla source
Il existe une explication typique de la raison
sed
pour laquelle des outils de traitement de flux de texte similaires ne sont pas bien équipés pour analyser des données structurées telles que JSON et XML. Je ne l'ai pas sous la main, mais cela existe, et je pense que le fait est que les expressions nécessaires dans toutes les situations, mais probablement le moins, deviennent rapidement très complexes, tandis que les outils alternatifs conçus spécifiquement pour analyser la structure sont plus élégant, lisible et efficace dans la même analyse.Comme muru l' a fait dans un commentaire ,
jq
devrait être le bon outil pour le travail. Je peux également en témoigner personnellement étant très excité de le voir remplacer plusieurs fois où j'ai essayé d'analyser les mêmes données sans succès ou sans succès. Il contient même une grande capacité de formatage et de contrôle de la sortie. Je le préfère àjsontool
une raison ou plus que j'oublie actuellement.Byte Commander semble recommander
jshon
dans une autre réponse . Je n'ai pas utilisé cet outil, mais il me rappellexmlstarlet
et sa syntaxe, également avec une présentation personnalisable pour la sortie.la source
jsontool
peut être utilisé pour le cas spécifique de OPjq
que muru et heemayl décrivent qui ont déjà des exemples, et je poste simplement le raisonnement derrière cela: askubuntu.com/a/863948/230721Juste un autre outil Json appelé json ( https://github.com/trentm/json )
Cette étude de cas est trompeuse: il semble que les outils ne fonctionnent pas. Vous pouvez également utiliser
json
pour changer les fichiers json:ou même...
documentation dans: http://trentm.com/json/
s'il n'est pas installé:
npm install -g json
la source