Tengo este texto json:
{
"buildStatus" : {
"status" : "ERROR",
"conditions" : [{
"status" : "OK",
"metricKey" : "bugs"
}, {
"status" : "ERROR",
"metricKey" : "test_success_density"
}, {
"status" : "OK",
"metricKey" : "vulnerabilities"
}
],
"periods" : []
}
}
Quiero extraer el estado general de buildStatus, es decir, el resultado esperado era "ERROR"
"buildStatus" : {
"status" : "ERROR",
....
}
Intenté la expresión sed a continuación, pero no funciona, regresa OK
:
status= sed -E 's/.*\"buildStatus\":.*\"status\":\"([^\"]*)\",.*/\1/' jsonfile
¿Qué estoy haciendo mal?
fuente
jq
:jq -r .buildStatus.status
Trabajo para
jq
:Se puede acortar a:
-r
(--raw-output
) genera la cadena sinjson
formato de cadena, es decir, sin comillas.Ejemplo:
Si aún no está instalado, instálelo por (disponible en el repositorio de Universe):
fuente
Como se ha mencionado, es preferible analizar datos estructurados complejos con la API adecuada. Python tiene un
json
módulo para eso, que personalmente utilizo mucho en mis scripts, y es bastante fácil extraer los campos deseados que desee de esta manera:Lo que sucede aquí es que redirigimos el archivo de entrada al stdin de Python y lo leemos con
json.load()
. Eso se convierte en un diccionario de Python con la clave "buildStatus", y contiene otro diccionario de Python con la clave "status". Por lo tanto, simplemente estamos imprimiendo el valor de una clave en un diccionario que está almacenado en otro diccionario. Bastante sencillo.Además de la simplicidad, otra ventaja es que python y esta API están preinstalados y vienen con Ubuntu de forma predeterminada.
fuente
De hecho, puede hacerlo
sed
, pero le recomiendo encarecidamente que use un lenguaje más sofisticado que tenga herramientas escritas para manejar datos JSON. Puedes probar perl o python, por ejemplo.Ahora, en su ejemplo simple, todo lo que desea es la primera aparición de
"status"
, por lo que podría hacer:El truco es usar
-n
para evitar la impresión, luego, si la línea coincidestatus
(/status/
), elimina todo menos la parte que deseas/.*:\s*"(.*)",/\1/
,p
enjuague la línea yq
uit.Personalmente, este comando grep equivalente me parece mucho más simple:
O este:
Sin embargo, si planea analizar archivos JSON, no intente hacerlo manualmente. Use un analizador JSON adecuado.
fuente
grep -m 1 status file.json | tr -cd '[[:alnum:]]:' | cut -f2 -d':'
No digo que debas usar
sed
(creo que alguien me ha votado negativamente solo por no escribir una advertencia obligatoria) pero, si necesitas buscar algo en la siguiente línea,buildStatus
ya que parece que estás intentando en tu propio intento, debes decirlesed
que lea la siguiente línea con elN
comandoNotas:
-n
no imprima nada hasta que lo solicitemos-r
usar ERE (igual que-E
)/buildStatus/N
encuentra este patrón y lee la siguiente línea tambiéns/old/new/
reemplazarold
connew
.*
cualquier número de caracteres en la línea\n
nueva línea: "(.*)",
guardar los caracteres que ocurran entre: "
y",
\1
referencia posterior al patrón guardadop
imprime la parte en la que trabajamosfuente
Hay una explicación típica de por qué
sed
y herramientas de procesamiento de flujo de texto similares no están bien equipadas para analizar datos estructurados como JSON y XML. No tengo eso a mano, pero está ahí afuera, y creo que el punto es que las expresiones necesarias en todas, pero probablemente en la menor cantidad de situaciones, rápidamente se vuelven muy complejas, mientras que las herramientas alternativas creadas específicamente para analizar la estructura son más elegante, legible y eficiente al mismo análisis.Como Muru ha puesto en un comentario ,
jq
debería ser la herramienta adecuada para el trabajo. También puedo dar fe de que personalmente estoy muy emocionado de ver que se reemplaza varias veces en las que he intentado analizar los mismos datos casi sin éxito o con un gran peso. Incluso contiene una gran capacidad para formatear y controlar la salida. Lo prefierojsontool
por una razón o más que actualmente olvido.Byte Commander parece recomendar
jshon
en otra respuesta . No he usado esa herramienta, pero me recuerdaxmlstarlet
y su sintaxis, también con alguna presentación personalizable para la salida.fuente
jsontool
se puede usar para el caso específico de OPjq
que muru y heemayl describan que ya tienen ejemplos, y solo publiquen el razonamiento detrás de esto: askubuntu.com/a/863948/230721Simplemente otra herramienta Json llamada json ( https://github.com/trentm/json )
Este estudio de caso es engañoso: parece que las herramientas no funcionan. También puede usar
json
para cambiar archivos json:o incluso...
documentación en: http://trentm.com/json/
si no está instalado:
npm install -g json
fuente