
Para ser claros: quiero una salida pseudo-JSON que se escribirá en otro archivo JSON estático aquí... así que no estará envuelta en una matriz ni nada por el estilo, simplemente obteniendo las comas que faltan después de cada entidad en mi salida.
Actualmente mi consulta es:
.[] | select(.auditId == "categories") |
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*\(.auditProperty):* \(.actual) (expected \(.expected))"
}
}
Qué salidas:
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*performance:* 1 (expected 0.8)"
}
}
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*accessibility:* 1 (expected 0.9)"
}
}
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*best-practices:* 0.96 (expected 0.9)"
}
}
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*seo:* 0.64 (expected 0.5)"
}
}
Cuando en realidad quiero:
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*performance:* 1 (expected 0.8)"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*accessibility:* 1 (expected 0.9)"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*best-practices:* 0.96 (expected 0.9)"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*seo:* 0.64 (expected 0.5)"
}
},
¡Tenga en cuenta la coma después de cada entidad! Me está volviendo loco, he intentado agregar a join(", ")
en varios lugares pero eso no afecta el resultado final o no se compila dependiendo de dónde lo coloque.
Aqui esta el jqplay con datos incluidoshttps://jqplay.org/s/xx3F_IWn03g
JSON de entrada original:
[
{
"name": "minScore",
"expected": 0.8,
"actual": 1,
"values": [
1,
1,
1
],
"operator": ">=",
"passed": true,
"auditProperty": "performance",
"auditId": "categories",
"level": "error",
"url": "http://localhost:8080/page2"
},
{
"name": "minScore",
"expected": 0.9,
"actual": 1,
"values": [
1,
1,
1
],
"operator": ">=",
"passed": true,
"auditProperty": "accessibility",
"auditId": "categories",
"level": "error",
"url": "http://localhost:8080/page2"
},
{
"name": "minScore",
"expected": 0.9,
"actual": 0.96,
"values": [
0.93,
0.96,
0.96
],
"operator": ">=",
"passed": true,
"auditProperty": "best-practices",
"auditId": "categories",
"level": "error",
"url": "http://localhost:8080/page2"
},
{
"name": "minScore",
"expected": 0.5,
"actual": 0.64,
"values": [
0.64,
0.64,
0.64
],
"operator": ">=",
"passed": true,
"auditProperty": "seo",
"auditId": "categories",
"level": "error",
"url": "http://localhost:8080/page2"
}
]
Respuesta1
Parece que quieresmodificarlas entradas que se han auditId
configurado en la cadena categories
. Lo que estás haciendo esextractoesos elementos de la matriz de nivel superior y modifíquelos. Esto le proporciona un conjunto (no una matriz) de objetos.
En lugar de usar |
para extraer elementos de la matriz, use|=
modificar sus elementos. Consulte el final de esta respuesta para saber cómo insertar correctamente la matriz resultante en una estructura JSON en otro archivo.
Entonces, usa
.[] |= (
select(.auditId == "categories") |
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*\(.auditProperty):* \(.actual) (expected \(.expected))"
}
}
)
Alternativamente, no lo use .[]
en absoluto y en su lugar usemap()
con la expresión de cada uno de los elementos de la matriz de nivel superior:
map(
select(.auditId == "categories") |
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*\(.auditProperty):* \(.actual) (expected \(.expected))"
}
}
)
Estas expresiones le darán una variedad de elementos como este:
[
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*performance:* 1 (expected 0.8)"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*accessibility:* 1 (expected 0.9)"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*best-practices:* 0.96 (expected 0.9)"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*seo:* 0.64 (expected 0.5)"
}
}
]
Para agregar esta matriz a una matriz ya existente en otro archivo, puede hacer esto (asumiendo que hay una array
clave en el nivel superior de otherfile
y que su entrada está en inputfile
; la clave se creará si aún no existe):
jq '.array += ( input |
map(
select(.auditId == "categories") |
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*\(.auditProperty):* \(.actual) (expected \(.expected))"
}
}
)
)' otherfile inputfile
Cuando input
se ejecuta, se lee la matriz del segundo archivo en la línea de comando.
Cambie +=
a just =
si desea reemplazar el array
valor de la clave existente en lugar de agregarlo.
Respuesta2
Sí, eso es lo que []
hace el iterador, obtienes un archivo JSON para cada uno. Para obtener una matriz, puede encerrar la expresión completa para [...]
crear una matriz a partir de ella o usarla map()
para modificar la matriz de entrada en su lugar en lugar de []
iterar sobre sus elementos.
$ echo '[1,2,3,4]' | jq '.[]|select(.<3)'
1
2
$ echo '[1,2,3,4]' | jq '[.[]|select(.<3)]'
[
1,
2
]
$ echo '[1,2,3,4]' | jq 'map(select(.<3))'
[
1,
2
]
Al tener elementos separados por comas sin el carácter adjunto [
, ]
convertirlo en una matriz haría que el json no sea válido, pero si eso es lo que desea, puede canalizarlo sed '1d;$d'
para eliminar la primera y la última línea.