Removendo várias linhas

1

Estou tentando escrever uma interface de linha de comando que removerá uma seção / linha particular de códigos dentro de uma lista de arquivos json. By the way, o arquivo json estão localizados dentro das sub-pastas do diretório principal

Eu sou muito novo nisso, mas este é o código que eu posso criar até agora - find -name "*.json" | xargs sed -i "map" mas alguns dos arquivos json que eu tinha, seu formato é um pouco diferente

Até agora, estou vendo os dois formatos a seguir na minha lista:

{
    "tags": {}, 
    "map": {
        "KPA": {
            "State": True, 
            "namespace": "KPA01"
        }
    }
}

ou

{
    "tags": {
        "type": [
            "char"
        ], 
        "dynamic": true
    }, 
    "map": {
        "KPA01": {
           "State": True, 
            "namespace": "KPA01"
        }
    }
}

e, basicamente, estou tentando omitir a seção do mapa que ela possui, para que ela exiba apenas a seção de tags, mas a presença de vírgulas e [] / {} estão dificultando para mim. Então, meus resultados de saída devem ser assim:

{
    "tags": {}
}

ou

{
    "tags": {
        "type": [
            "char"
        ], 
        "dynamic": true
    }
}

Isso será possível em uma interface de linha de comando? Ouvi dizer que jq pode ser capaz de fazê-lo, no entanto, como eu tentei executar jq '.map' test.json estou recebendo parse error: ':' not as part of an object at line 2, column 11 no meu terminal. Da mesma forma, também parece estar havendo erro se eu estiver usando o jq play online ..

Alguma idéia?

    
por dissidia 27.01.2015 / 08:45

3 respostas

2

Primeiro, altere True para true . Como um todo, isso funciona muito bem:

#!/usr/bin/python
import sys
import json

inputfile = sys.argv[1]
with open(inputfile,'r') as myfile:
    obj = json.loads(myfile.read().replace('True','true'))
    if "map" in obj:
        del obj["map"]
    json.dump(obj,sys.stdout,indent=4,separators=(',',': '))

Isso grava na saída padrão.

EDIT: a versão anterior parece ser um pouco perigosa. Melhor fazer assim:

#!/usr/bin/python
import sys
import json

inputfile = sys.argv[1]
with open(inputfile,'r') as myfile:
    obj = json.loads(myfile.read().replace('True','true'))
    if "map" in obj:
        del obj["map"]
with open(inputfile,'w') as myfile:
    json.dump(obj,myfile,indent=4,separators=(',',': '))

Como o script está realmente ciente do que é um JSON válido, ele lançará uma exceção se encontrar um código inválido, em vez de produzir uma saída imprevisível.

Isso funciona no python 3, só para você saber.

EDIT2:

Você pode modificar os objetos da maneira que quiser, a finalidade do Json é exatamente a serialização de objetos. Trate-os como matrizes associativas e dê a eles qualquer valor que você quiser. Por exemplo, você pode fazer isso:

#add a new string on the "ground" level
obj["new_key"]="lol"
#add a new subarray, with properties of different types
obj["this_is_array"]={"a": 3, "b": 16, "c": "string", "d": False }
#modify the value of existing field
obj["new_key"]="new value"
#insert into subarray (test if it exists first)
if "this_is_array" in obj:
    obj["this_is_array"]["e"]=42
    
por 27.01.2015 / 10:24
1

Se você manipular o True > true como mencionado em outro lugar e obtenha a ferramenta jq , você pode fazer:

jq '{tags}' <infile

Por exemplo, depois de copiar um dos seus exemplos para minha área de transferência:

xsel -bo | sed 's/True/true/g' | jq '{tags}'

OUTPUT:

{
  "tags": {
    "type": [
      "char"
    ],
    "dynamic": true
  }
}
    
por 27.01.2015 / 10:40
0

Eu encontrei o mesmo erro:

parse error: Invalid numeric literal at line 5, column 26

e eu não estou acostumado a mas acho que True deve estar em minúsculas, como true , para que você possa executar uma one-liner para corrigir e usar jq para filtrar a chave map , como:

perl -pe 's/(\W)T(rue)/$1t$2/g' file1.json | ./jq 'del(.map)'

para o primeiro exemplo, isso produz:

{
  "tags": {}
}

e:

perl -pe 's/(\W)T(rue)/$1t$2/g' file2.json | ./jq 'del(.map)'

para o segundo, que produz:

{
  "tags": {
    "type": [
      "char"
    ],
    "dynamic": true
  }
}
    
por 27.01.2015 / 10:07