[
{
"name": "user1",
"status": "off"
},
{
"name": "user2",
"status": "off"
},
{
"name": "user3",
"status": "on"
}
]
Quero saber como posso pesquisar recursivamente um arquivo JSON pelo valor de status
, por exemplo, off
e obter todos os name
valores para os quais o status é off
.
Além disso, como posso alterar o valor para user1
e user2
para on
?
Estou usando jq
e bash
.
Para aplicar uma expressão a todos os elementos de uma matriz e obter uma matriz alterada, use
map(expression)
.Extraindo todas as entradas que possuem
off
status:O mapeamento
select(.status == "off")
alterará a matriz extraindo (selecionando) apenas os elementos para os quais.status == "off"
é true .Extraindo apenas os nomes decodificados do acima:
Colocar no
[].name
final da expressão anterior primeiro expandirá a matriz em um conjunto de entradas individuais (é isso que[]
faz) e, em seguida, extrairá o.name
valor de cada uma delas.Você também poderia ter usado
... que cria um array de nomes dos quais você extrai todos os elementos.
Configurando o status como
on
para todas as entradas que possuem umoff
status:Ao mapear
select(.status == "off").status = "on"
, modificamos nosso array definindo o statuson
para qualquer elemento cujo status sejaoff
.Configurando o status
on
para entradas com base em nomes explícitos:A mesma coisa, mas não codifique os nomes dentro da expressão. Em vez disso, forneça-os como uma lista no final da linha de comando (observe que
--args
e a lista de nomes deve ser a última coisa na linha de comando):A lista de nomes dada
--args
é encontrada no array chamado$ARGS.positional
.A
IN(a; b)
coisa retorna true sea
aparecer no setb
. Estamos usando$ARGS.positional[]
como o conjunto de pesquisa, que é o conjunto dos nomes fornecidos na linha de comando. Isso significa que nossoselect()
aqui extrairá apenas os elementos cujos nomes ocorrem na lista na linha de comando, e estes terão seu status definido comoon
.Observe que
IN(a; b)
difere do nome semelhantein(a)
, que retorna true se um determinado valor ocorrer como uma chave ou índice no objeto ou arraya
.Configurando o status de todas as entradas para
on
:Pergunta complementar nos comentários:
O seguinte usa uma instrução explícita
if
para alterar o statuson
para os nomes fornecidos eoff
para todos os outros:Ou, em um layout de uma linha:
Se, em vez disso, eu interpretar o acompanhamento como não querendo alterar o status dos nomes fornecidos, não importa quais sejam seus status, mas para alterar todos os outros status para
off
. Nesse caso, podemos negar a condição usada em uma variação anterior:Observe o adicionado
| not
apósIN(...; ...)
.Claro, você poderia ter usado uma
if
declaração na maioria das variações acima também, mas eu gosto de usarselect()
quando posso.