Usando vários curingas em jq para selecionar objetos em um arquivo JSON

1

Eu tenho um arquivo JSON com milhares de registros linha por linha na estrutura a seguir, com valores diferentes.

Exemplo:

{"in": 5,"li": [{"st": 1508584161,"abc": 128416626,"ta": 33888}],"usr": {"is": "222108923573880","ie": "222108923573880"},"st2": 1508584161,"ei": {"ev": 0,"rt": 10},"rn": 947794,"st1": 1508584161}
{"in": 5,"li": [{"st": 1508584174,"abc": 128572802,"ta": 33504}],"usr": {"is": "222108923573880","ie": "222108923573880"},"st2": 1508584174,"ei": {"ev": 0,"rt": 19},"rn": 947795,"st1": 0}
{"in": 5,"li": [{"st": 1508584145,"abc": 279682,"ta": 50000}],"usr": {"is": "222108923573880","ie": "222108923573880"},"st2": 1508584145,"ei": {"ev": 0,"rt": 18},"rn": 947796,"st1": 1508584145}
{"in": 5,"li": [{"st": 1508584183,"abc": 1378680,"ta": 49840}],"usr": {"is": "222108923573880","ie": "222108923573880"},"st2": 1508584183,"ei": {"ev": 0,"rt": 10},"rn": 947797,"st1": 1508584186}
{"nt": 4}

Estou tentando selecionar objetos (registros) no arquivo JSON que correspondem aos seguintes critérios e saída para outro arquivo.

st1 é < ou = st2

st1 não é 0

st2 não é 0

st1 é menor que 2147483647

st2 é menor que 2147483647

Na saída, o rodapé do arquivo original ({"nt": 4}) também deve estar no arquivo de saída, para que possa ser editado com a nova contagem de registros

Exemplo de arquivo de saída:

{"in": 5,"li": [{"st": 1508584161,"abc": 128416626,"ta": 33888}],"usr": {"is": "222108923573880","ie": "222108923573880"},"st2": 1508584161,"ei": {"ev": 0,"rt": 10},"rn": 947794,"st1": 1508584161} 
{"nt": 1}

Eu tenho o seguinte:

jq -c 'select((.st1 > 0 and .st2 > 0 and .st1 < .st2) or (.st1 < 214748647 and .st2 < 214748647 and .st1 > 0 and .st2 > 0 and .st1 < .st2)) file.json

Eu tentei várias permutações, mas não está capturando os registros corretos.

    
por Booboo 15.11.2017 / 12:22

1 resposta

0

Com os números corretos, uma tradução direta de suas condições funciona:

$ jq -c 'select(.st1 <= .st2 and 
                .st1 > 0 and .st2 > 0 and 
                .st1 < 2147483647 and .st2 < 2147483647)' file.json 
{"in":5,"li":[{"st":1508584161,"abc":128416626,"ta":33888}],"usr":{"is":"222108923573880","ie":"222108923573880"},"st2":1508584161,"ei":{"ev":0,"rt":10},"rn":947794,"st1":1508584161}
{"in":5,"li":[{"st":1508584145,"abc":279682,"ta":50000}],"usr":{"is":"222108923573880","ie":"222108923573880"},"st2":1508584145,"ei":{"ev":0,"rt":18},"rn":947796,"st1":1508584145}

Observe o fechamento de ' e nenhum parêntese duplo. Eu não entendo porque você divide as condições em duas cláusulas and conectadas por or , não é isso que suas condições dizem.

De qualquer forma, isso captura os registros corretos; agora só temos que adicionar o rodapé. Isso é mais fácil com um passo adicional, encurtando a cláusula select de cima para brevidade:

jq -c 'select ...' file.json > out.json
printf '{"nt":%i}\n' 'wc -l < out.json' >> out.json 

Acho que também é possível fazer isso com uma expressão jq complicada, mas não tentei isso.

    
por 16.11.2017 / 14:03