AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 719310
Accepted
decipher
decipher
Asked: 2022-10-01 08:48:51 +0800 CST2022-10-01 08:48:51 +0800 CST 2022-10-01 08:48:51 +0800 CST

Como verificar um valor e alterar outra chave em JSON com jq?

  • 772
[
    {
        "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, offe obter todos os namevalores para os quais o status é off.

Além disso, como posso alterar o valor para user1e user2para on?

Estou usando jqe bash.

text-processing json
  • 1 1 respostas
  • 200 Views

1 respostas

  • Voted
  1. Best Answer
    Kusalananda
    2022-10-01T09:03:44+08:002022-10-01T09:03:44+08:00

    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 offstatus:

    $ jq 'map(select(.status == "off"))' file
    [
      {
        "name": "user1",
        "status": "off"
      },
      {
        "name": "user2",
        "status": "off"
      }
    ]
    

    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:

    $ jq -r 'map(select(.status == "off"))[].name' file
    user1
    user2
    

    Colocar no [].namefinal da expressão anterior primeiro expandirá a matriz em um conjunto de entradas individuais (é isso que []faz) e, em seguida, extrairá o .namevalor de cada uma delas.

    Você também poderia ter usado

    jq -r 'map(select(.status == "off").name)[]' file
    

    ... que cria um array de nomes dos quais você extrai todos os elementos.

    Configurando o status como onpara todas as entradas que possuem um offstatus:

    $ jq 'map(select(.status == "off").status = "on")' file
    [
      {
        "name": "user1",
        "status": "on"
      },
      {
        "name": "user2",
        "status": "on"
      },
      {
        "name": "user3",
        "status": "on"
      }
    ]
    

    Ao mapear select(.status == "off").status = "on", modificamos nosso array definindo o status onpara qualquer elemento cujo status seja off.

    Configurando o status onpara entradas com base em nomes explícitos:

    $ jq 'map(select(.name == "user1" or .name == "user2").status = "on")' file
    [
      {
        "name": "user1",
        "status": "on"
      },
      {
        "name": "user2",
        "status": "on"
      },
      {
        "name": "user3",
        "status": "on"
      }
    ]
    

    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 --argse a lista de nomes deve ser a última coisa na linha de comando):

    $ jq 'map(select(IN(.name; $ARGS.positional[])).status = "on")' file --args user1 user2
    [
      {
        "name": "user1",
        "status": "on"
      },
      {
        "name": "user2",
        "status": "on"
      },
      {
        "name": "user3",
        "status": "on"
      }
    ]
    

    A lista de nomes dada --argsé encontrada no array chamado $ARGS.positional.

    A IN(a; b)coisa retorna true se aaparecer no set b. Estamos usando $ARGS.positional[]como o conjunto de pesquisa, que é o conjunto dos nomes fornecidos na linha de comando. Isso significa que nosso select()aqui extrairá apenas os elementos cujos nomes ocorrem na lista na linha de comando, e estes terão seu status definido como on.

    Observe que IN(a; b)difere do nome semelhante in(a), que retorna true se um determinado valor ocorrer como uma chave ou índice no objeto ou array a.

    Configurando o status de todas as entradas para on:

    $ jq 'map(.status = "on")' file
    [
      {
        "name": "user1",
        "status": "on"
      },
      {
        "name": "user2",
        "status": "on"
      },
      {
        "name": "user3",
        "status": "on"
      }
    ]
    

    Pergunta complementar nos comentários:

    E se eu quiser combinar como NOT IN(a, b), então? Claramente, estou perguntando se passo valor como user1e desativa todos os outros, exceto user1. Como posso fazer isso?

    O seguinte usa uma instrução explícita ifpara alterar o status onpara os nomes fornecidos e offpara todos os outros:

    jq '
        map(
            if IN(.name; $ARGS.positional[]) then
                .status = "on"
            else
                .status = "off"
            end
        )' file --args user1
    

    Ou, em um layout de uma linha:

    jq 'map(if IN(.name; $ARGS.positional[]) then .status = "on" else .status = "off" end)' file --args user1
    

    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:

    jq 'map(select(IN(.name; $ARGS.positional[]) | not).status = "off")' file --args user1
    

    Observe o adicionado | notapós IN(...; ...).

    Claro, você poderia ter usado uma ifdeclaração na maioria das variações acima também, mas eu gosto de usar select()quando posso.

    • 10

relate perguntas

  • Subtraindo a mesma coluna entre duas linhas no awk

  • chave de impressão jq e valor para todos no subobjeto

  • jq adicionar ou atualizar um valor com vários --arg

  • Embaralhamento de arquivo de várias linhas

  • como posso alterar o caso do caractere (de baixo para cima e vice-versa)? ao mesmo tempo [duplicado]

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve