
Para ser claro - eu quero uma saída pseudo-JSON que será escrita em outro arquivo JSON estático aqui ... portanto, não agrupada em uma matriz ou algo assim, simplesmente obtendo as vírgulas ausentes após cada entidade em minha saída.
Atualmente minha consulta é:
.[] | select(.auditId == "categories") |
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*\(.auditProperty):* \(.actual) (expected \(.expected))"
}
}
Quais saídas:
{
"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)"
}
}
Quando na verdade eu quero:
{
"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)"
}
},
Observe a vírgula após cada entidade! Isso está me deixando maluco, tentei adicionar um join(", ")
em vários lugares, mas isso não faz nada na saída final ou não consegue compilar dependendo de onde eu o coloco.
Aqui está o jqplay com dados incluídoshttps://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"
}
]
Responder1
Você parece querermodificaras entradas que foram auditId
definidas para a string categories
. O que você está fazendo éextrairesses elementos da matriz de nível superior e modificá-los. Isso fornece um conjunto (não uma matriz) de objetos.
Em vez de usar |
para extrair elementos do array, use|=
modificar seus elementos. Veja o final desta resposta para saber como inserir corretamente o array resultante em uma estrutura JSON em outro arquivo.
Então, use
.[] |= (
select(.auditId == "categories") |
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*\(.auditProperty):* \(.actual) (expected \(.expected))"
}
}
)
Como alternativa, não use .[]
nada e, em vez disso, usemap()
com a expressão em cada um dos elementos da matriz de nível superior:
map(
select(.auditId == "categories") |
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*\(.auditProperty):* \(.actual) (expected \(.expected))"
}
}
)
Essas expressões fornecerão uma série 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 adicionar esse array a um array já existente em outro arquivo, você pode fazer isso (assumindo que existe uma array
chave no nível superior otherfile
e que sua entrada está em inputfile
; a chave será criada se ainda não existir):
jq '.array += ( input |
map(
select(.auditId == "categories") |
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*\(.auditProperty):* \(.actual) (expected \(.expected))"
}
}
)
)' otherfile inputfile
Quando input
é executado, o array do segundo arquivo na linha de comando é lido.
Mude +=
para apenas =
se desejar substituir o array
valor da chave existente em vez de adicioná-lo.
Responder2
Sim, é isso que o []
iterador faz, você obtém um arquivo JSON para cada um. Para obter uma matriz, você pode incluir a expressão inteira para [...]
criar uma matriz a partir dela ou usá-la map()
para modificar a matriz de entrada no local, em vez de []
iterar sobre seus 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
]
Ter elementos separados por vírgula sem o fechamento [
, ]
para torná-lo um array tornaria o json inválido, mas se é isso que você deseja, você pode canalizá-lo sed '1d;$d'
para excluir a primeira e a última linhas.