Extrai o elemento da matriz json com base em um valor de subelemento

2

Temos o seguinte arquivo de exemplo (arquivo muito longo, este é um exemplo curto)

"request_status" : "FAILED"
{
    "href" : "http://localhost:8080/api/v1/clusters/sys41/requests/333",
    "Requests" : {
        "cluster_name" : "sys41",
        "id" : 333,
        "request_status" : "COMPLETED"
    }
},
{
    "href" : "http://localhost:8080/api/v1/clusters/sys41/requests/334",
    "Requests" : {
        "cluster_name" : "sys41",
        "id" : 334,
        "request_status" : "FAILED"
    }
},
{
    "href" : "http://localhost:8080/api/v1/clusters/sys41/requests/335",
    "Requests" : {
        "cluster_name" : "sys41",
        "id" : 335,
        "request_status" : "FAILED"
    }
},
{
    "href" : "http://localhost:8080/api/v1/clusters/sys41/requests/336",
    "Requests" : {
        "cluster_name" : "sys41",
        "id" : 336,
        "request_status" : "COMPLETED"
    }
}

como imprimir a linha depois da linha que corresponde a "id" : $num
por exemplo. para

num=335 

como obter a linha depois

"id" : $num

Saída esperada

"request_status" : "FAILED"
    
por yael 05.03.2018 / 18:09

3 respostas

1

Dado a variável de shell num definida como 335 :

grep -A1 "\"id\" : $num," /path/to/file

Eu obtenho muita milhagem das opções grep , -A e -B do-C, os mnemônicos que eu uso são "Depois", "Antes" e "Contexto" .

  • grep -A n 'pattern' file mostrará as linhas n A após uma correspondência de padrão, além da própria linha correspondente.

  • grep -C n 'pattern' file mostrará as linhas n B antes de uma correspondência de padrões, além da própria linha correspondente.

  • grep -C n 'pattern' file mostrará as linhas n antes e após (ou seja, o C ontext de) uma correspondência de padrão, além da própria linha correspondente.

por 05.03.2018 / 18:17
6

Supondo que o arquivo JSON é uma grande variedade de objetos, como

  {
    "href": "http://localhost:8080/api/v1/clusters/sys41/requests/333",
    "Requests": { "id": 333, "cluster_name": "sys41", "request_status": "COMPLETED" }
  },

(observando que as novas linhas não são significativas e nem a ordenação das chaves em um objeto), o seguinte comando jq obteria a entrada request_status para a id correspondente a $num :

$ num=355
$ jq -r ".[].Requests | select(.id == $num).request_status" file.json
FAILED

Ele faz isso escolhendo todas as entradas Requests de cada objeto e filtrando-as no id . Para aqueles que passam o filtro, ele extrai request_status .

A opção -r para jq faz com que ela exiba dados brutos em vez de JSON ( FAILED teria sido duplicado sem ela).

Material bônus:

$ jq -r '.[].Requests | "\(.id): \(.request_status)"' file.json
333: COMPLETED
334: FAILED
335: FAILED
336: COMPLETED
    
por 05.03.2018 / 18:45
1
awk '/"id" : 335/{getline;print}'

ou

var="\"id\" : 335"
awk "/$var/{getline;print}"

ou

awk -v var="\"id\" : 335" '$0~var{getline;print}'

ou

var="\"id\" : 335"
awk -v var="$var" '$0~var{getline;print}'

ou qualquer um dos itens acima, mas sem precisar da parte "id" : " da string, na forma:

awk -v var="335" '$0~"id" : var{getline;print}'
    
por 05.03.2018 / 18:18