Converte o objeto de mapeamento json para a linha csv gerenciada usando o script bash

0

Eu tenho o json mapeado sob properties key como abaixo em um arquivo Customer.json,

{
    "customer": {
        "properties": {
            "customerId": {
                "type": "string",
                "index": "not_analyzed"
            },
            "name": {
                "type": "string",
                "index": "not_analyzed"
            }
        }
    }
}

Que eu quero converter em seguinte com key e displayName duplicado e type do mapeamento acima,

field(key: 'customerId',     displayName: 'customerId', type: 'String')
field(key: 'name',           displayName: 'name',       type: 'String')

Eu bati e tentei bash + python como abaixo, assumindo que ele buscou a chave do cliente primeiro e faz um loop dentro das propriedades,

$ cat Customer.json | python -c 'import sys; import simplejson as json; \
print "\n".join( [i["properties"] for i in json.loads( sys.stdin.read() )["customer"]] )'

Traceback (most recent call last):
File "<string>", line 2, in <module>
TypeError: string indices must be integers, not str

Estou aberto a outras soluções também.

    
por prayagupd 04.07.2014 / 07:40

2 respostas

1

A análise desses dados estruturados é melhor feita usando um analisador dedicado, exatamente como você está fazendo. No entanto, neste caso em particular, é bastante simples que você poderia fazer:

$ grep -B 1 '"type":' Customer.json | tr $'"' $"'" | sed 's/[:,]//g' | 
    awk '{print "field(key: "$1",\tdisplayName: "$1",\t type: "$NF")"}' RS="--" 

Que retorna:

field(key: 'customerId',    displayName: 'customerId',   type: 'string')
field(key: 'name',  displayName: 'name',     type: 'string')
    
por 04.07.2014 / 11:06
1

O erro parece claro para mim, a variável "i" é uma string, pois o loop for itera sobre o valor do dict / mapping "customer". Esse valor é um próprio ditador / mapeamento e iterar sobre ele irá levá-lo a sucessão da lista de chaves (ou seja, ["propriedades"].

cat Customer.json |  python -c 'import sys; import simplejson as json; \
print "\n".join( [i for i in json.loads( sys.stdin.read() )["customer"]["properties"] ] )'

vai te dar

 customerid
 name

e o seguinte deve aproximá-lo do seu objetivo:

cat Customer.json |  python -c 'import sys; import simplejson as json; \
print "\n".join( ["{} {}".format(k, v) for k,v in json.loads( sys.stdin.read() )["customer"]["properties"].iteritems() ] )'

que dá:

customerId {'index': 'not_analyzed', 'type': 'string'}
name {'index': 'not_analyzed', 'type': 'string'}

De lá, eu recomendo que você realmente faça o python em um script. Você terá que decidir como ir de string a String e fazer a formatação adicional. Um multiliner é sempre mais fácil de depurar (caso seja comprovado pela sua pergunta) e pode ser mantido e fornece mensagens de erro mais significativas (números de linha).

    
por 04.07.2014 / 08:42