shell-script-pt
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [shell-script-pt] Ajuda para montar um json a partir de um CSV.


From: Arkanon
Subject: Re: [shell-script-pt] Ajuda para montar um json a partir de um CSV.
Date: Sat, 25 Dec 2021 14:51:03 -0300

Exatamente minha sugestão original, Alfredo :)

TODO o segredo se resume em ordenar pelo 3º campo:

csv2json()
{
  local csv prev campos='state_code  term  FICO_RANGE  fico_range_min  fico_range_max  interest_rate'
  local $campos
  csv=$([[ -t 0 ]] && cat $1 || cat)
  printf "["
  sort -t, -k3,3 <<< "$csv" | while IFS=, read $campos
  do
    [[ $state_code ]] || continue # pula linhas em branco
    [[ $fico_range_min != $prev ]] && novo || printf ","
    printf "\n      \"$term\": \"$interest_rate\""
    prev=$fico_range_min
  done
  printf "\n    }\n  }\n\n]\n"
}

novo()
{
  printf "
${prev:+    \}\n  \},\n}
  {
    \"state_code\": \"$state_code\",
    \"fico_range_min\": \"$fico_range_min\",
    \"fico_range_max\": \"$fico_range_max\",
    \"interest_rate\":
    {"
}

$ cat tmp/mkjson/dados.csv

AK,12,700-719,700,719,0.1124
AK,12,720-739,720,739,0.1074
AK,12,740-759,740,759,0.1024
AK,12,760-779,760,779,0.0974
AK,12,780-799,780,799,0.0924
AK,12,800-819,800,819,0.0874
AK,12,820-850,820,850,0.0499

AK,36,700-719,700,719,0.1174
AK,36,720-739,720,739,0.1124
AK,36,740-759,740,759,0.1074
AK,36,760-779,760,779,0.1024
AK,36,780-799,780,799,0.0974
AK,36,800-819,800,819,0.0924
AK,36,820-850,820,850,0.0874
...

$ csv2json < dados.csv
[

  {
    "state_code": "AK",
    "fico_range_min": "700",
    "fico_range_max": "719",
    "interest_rate":
    {
      "12": "0.1124",
      "24": "0.1149",
      "36": "0.1174",
      "48": "0.1199"
    }
  },

...

  {
    "state_code": "AK",
    "fico_range_min": "820",
    "fico_range_max": "850",
    "interest_rate":
    {
      "12": "0.0499",
      "24": "0.0849",
      "36": "0.0874",
      "48": "0.0899",
      "60": "0.0949"
    }
  }

]




Em sáb., 25 de dez. de 2021 às 14:45, Alfredo Casanova <atcasanova@gmail.com> escreveu:
primeiro acho melhor tratar o input reordenado:

sort -n -k3 -t, input.csv

vai organizar o arquivo por creditscore
como a primeira taxa é sempre pra 12 prestações, podemos fazer:


#!/bin/bash
while IFS=, read state installments faixa mincred maxcred interest; do
# se for a primeira linha, preencha o novo bloco
(( installments == 12 )) && {
echo "{
\"stateCode\":\"$state\",
\"mincreditscore\":\"$mincred\",
\"maxcreditscore\":\"$maxcred\",
\"interestrate\": {
\"12\": \"$interest\","
} || {
maior=$(grep "$faixa" input.csv | cut -f2 -d, | sort -n | tail -1)
# se for a maior quantidade de parcelas, feche o bloco
(( maior == installments )) && {
echo "\"$installments\":\"$interest\"
}
}"
} || {
# se não, adicione a nova parcela
echo "\"$installments\":\"$interest\","
}
}
done < <(sort -n -k3 -t, input.csv) | jq '.'


image.png





On Fri, Dec 24, 2021 at 10:13 AM Alfredo Casanova <atcasanova@gmail.com> wrote:
https://miller.readthedocs.io/en/latest/


olha essa tool aqui, acho q te resolve mais facil

On Fri, Dec 24, 2021 at 12:14 AM Arkanon <arkanon@lsd.org.br> wrote:
Aliás, você está quase lá SE ordenou o csv adequadamente, claro :) Senão não nem adianta começar o loop.

Em sex., 24 de dez. de 2021 às 00:11, Arkanon <arkanon@lsd.org.br> escreveu:
Você está quase lá :)

Seu if deve testar se o valor de mincreditscore mudou. SE mudou, é porque começou um novo grupo de dados e NESSE CASO, deve ser escrita a sequencia de stateCode, mincreditscore e maxcreditscore. Caso contrario, ainda estará no mesmo grupo e portanto escreverá apenas os interestrate desse grupo. Mais as aspas, chaves, colchetes e vírgulas e "problem solved" :)

Em sex., 24 de dez. de 2021 às 00:00, George Robinson <george.robinson.br@gmail.com> escreveu:
Olá Arkanon!

Eu tbm preparei um loop num segundo script, mas me parece mais uma questão de entender arranjo e combinaçao. O meu loop falha pq eu caio na mesma questão de não conseguir rodar o loop com um if. Acredito que o ponto chave seja o fato de que o jq não é a melhor ferramenta para isso, visto que ao usá-lo, ele me parece ser muito direcionado a um parsing no arquivo, sem considerar as condiçoes envolvidas. Deixe-me mostrar até onde cheguei com o loop:

file=amostra.csv
while IFS=, read state_code,term,fico_range,fico_range_min,fico_range_max,interest_rate;
do
     if [[ $state_code == AK && "$term" == "12" ]]; then
          echo "{"
          echo '"stateCode": "$state_code"'
          echo '"State Min FICO": "$state_min_fico"'
          echo '"FICO Range Min": "$fico_range_min"'
          echo '"FICO Range Max": "$fico_range_max"'
          echo '"Interest Rate": {'
          echo "}"
echo "}"
     fi;
done < $file



Em qui., 23 de dez. de 2021 às 23:21, Arkanon <arkanon@lsd.org.br> escreveu:
Vamos começar determinando a melhor forma de ler os dados.

Com base na amostra, parece que o critério de agrupamento é mincreditscore. Possivelmente também stateCode, mas sua amostra não esclarece 100% esse ponto.
Então, se você ordenar o csv por esse(s) campo(s) vai deixá-los numa sequência adequada para serem lidos por um loop onde, sempre que o campo mincreditscore mudar, iniciará um novo dicionário com atributos stateCode, mincreditscore e maxcreditscore seguidos de um array de interestrate. aparentemente o terceiro campo do csv pode ser descartado.

O loop é apenas o método mais tradicional e óbvio de implementar o algoritmo, mas é bem possível que exista uma ferramenta que já faça essa tradução automaticamente. Não conheço jq suficientemente para afirmar se ele é ou não uma ferramenta adequada para essa conversão, tenho a impressão que não. Talvez uma ferramenta diretamente focada em csv.
Eu começaria correndo o risco de reinventar a roda e implementando o loop.

At.

Em qui., 23 de dez. de 2021 às 22:24, George Robinson <george.robinson.br@gmail.com> escreveu:
Pessoal,

Estou tentando um desafio particular para criar uma estrutura de dados em json a partir de um arquivo CSV. Eu solucionei parte do problema, e vou apresentá-lo abaixo:

1- Tenho um arquivo .csv com a seguinte estrutura de dados:
state_code,term,fico_range,fico_range_min,fico_range_max,interest_rate

AK,12,700-719,700,719,0.1124
AK,12,720-739,720,739,0.1074
AK,12,740-759,740,759,0.1024
AK,12,760-779,760,779,0.0974
AK,12,780-799,780,799,0.0924
AK,12,800-819,800,819,0.0874
AK,12,820-850,820,850,0.0499

AK,24,700-719,700,719,0.1149
AK,24,720-739,720,739,0.1099
AK,24,740-759,740,759,0.1049
AK,24,760-779,760,779,0.0999
AK,24,780-799,780,799,0.0949
AK,24,800-819,800,819,0.0899
AK,24,820-850,820,850,0.0849

AK,36,700-719,700,719,0.1174
AK,36,720-739,720,739,0.1124
AK,36,740-759,740,759,0.1074
AK,36,760-779,760,779,0.1024
AK,36,780-799,780,799,0.0974
AK,36,800-819,800,819,0.0924
AK,36,820-850,820,850,0.0874

AK,48,700-719,700,719,0.1199
AK,48,720-739,720,739,0.1149
AK,48,740-759,740,759,0.1099
AK,48,760-779,760,779,0.1049
AK,48,780-799,780,799,0.0999
AK,48,800-819,800,819,0.0949
AK,48,820-850,820,850,0.0899

AK,60,720-739,720,739,0.1199
AK,60,740-759,740,759,0.1149
AK,60,760-779,760,779,0.1099
AK,60,780-799,780,799,0.1049
AK,60,800-819,800,819,0.0999
AK,60,820-850,820,850,0.0949

Obs: coloquei a coloração para que fique claro que para cada item no campo term, temos praticamente os mesmos campos Range_min e Fico_Range_max, com seu respectivo interest_rate. Notem que essa configuração toda, refere-se ao mesmo state_code (AK). Então, basicamente, temos uma estrutura de dados que deveria sair assim:

{
"stateCode" : "AK",
    "mincreditscore" : "700",
    "maxcreditscore" : "719",
    "interestrate" : {
        "12" : "0.1024",
        "24" : "0.1149",
        "36" : "0.1174"
        "48" : "0.1199"
    }
}
{
"stateCode" : "AK",
    "mincreditscore" : "720",
    "maxcreditscore" : "739",
    "interestrate" : {
        "12" : "0.1074",
        "24" : "0.1099",
        "36" : "0.1124"
        "48" : "0.1149"
        "60" : "0.1199"
     }
}
{
"stateCode" : "AK",
    "mincreditscore" : "740",
    "maxcreditscore" : "759",
    "interestrate" : {
        "12" : "0.1024",
        "24" : "0.1049",
        "36" : "0.1074"
        "48" : "0.1099"
        "60" : "0.1149"
     }
}

e assim por diante...

Bom, sobre como vou montar esse json, eu poderia fazer com um echo ou printf, porém, decidi ler diretamente o arquivo utilizando a ferramenta jq.

tail -n +2 jqlookup.csv | jq -Rsn '
{"occurrences":
    [inputs
    | . / "\n"
    | (.[] | select(length > 0) | . / ",") as $input
    | {"product": "5a014b7094a4a92ba5fba4e1", "stateCode": $input[0], "mincreditscore": $input[3], "maxcreditscore": $input[4], "interestrate": {"12": $input[5], "24": $input[5], "36": $input[5]}}]}'

O que obviamente não deu certo, pois ele monta a estrutura linha a linha, conforme solicitado no comando acima.

O que eu preciso é que dentro da estrutura, seja possível capturar as propriedades do campo interestrate de acordo com o term, ou seja, para cada fico_range, eu possa agrupar os valores de term (12,24,36,48 ou 60) juntoc om o fico_range e colocar o valor de interest_rate. para produzir aquela saída que exemplifiquei.

Não precisa ser com jq... pode ser com printf, echo... desde que seja produzida a estrutura acima.

Muito obrigado desde já!
--
George Robinson
Analista de Suporte
Tel: +55 (21) 97449-8138
_______________________________________________
Lista brasileira de usuários de shell script
Endereço de e-mail da lista: shell-script-pt@nongnu.org
Para se inscrever ou desinscrever acesse: https://lists.nongnu.org/mailman/listinfo/shell-script-pt
Para ver os arquivos da lista (mensagens anteriores) e pesquisar nelas, acesse https://lists.nongnu.org/archive/html/shell-script-pt/

NOTA: A lista anterior, no Yahoo Groups, foi *desativada*. Por favor utilize somente esta.


--
(o_  @arkanon  (Twitter)     __o
//\   arkanon@lsd.org.br   _`\<,
V_/_      www.lsd.org.br  (_)/(_)
---------------------------------
_______________________________________________
Lista brasileira de usuários de shell script
Endereço de e-mail da lista: shell-script-pt@nongnu.org
Para se inscrever ou desinscrever acesse: https://lists.nongnu.org/mailman/listinfo/shell-script-pt
Para ver os arquivos da lista (mensagens anteriores) e pesquisar nelas, acesse https://lists.nongnu.org/archive/html/shell-script-pt/

NOTA: A lista anterior, no Yahoo Groups, foi *desativada*. Por favor utilize somente esta.


--
George Robinson
Analista de Suporte
Tel: +55 (21) 97449-8138
_______________________________________________
Lista brasileira de usuários de shell script
Endereço de e-mail da lista: shell-script-pt@nongnu.org
Para se inscrever ou desinscrever acesse: https://lists.nongnu.org/mailman/listinfo/shell-script-pt
Para ver os arquivos da lista (mensagens anteriores) e pesquisar nelas, acesse https://lists.nongnu.org/archive/html/shell-script-pt/

NOTA: A lista anterior, no Yahoo Groups, foi *desativada*. Por favor utilize somente esta.


--
(o_  @arkanon  (Twitter)     __o
//\   arkanon@lsd.org.br   _`\<,
V_/_      www.lsd.org.br  (_)/(_)
---------------------------------


--
(o_  @arkanon  (Twitter)     __o
//\   arkanon@lsd.org.br   _`\<,
V_/_      www.lsd.org.br  (_)/(_)
---------------------------------
_______________________________________________
Lista brasileira de usuários de shell script
Endereço de e-mail da lista: shell-script-pt@nongnu.org
Para se inscrever ou desinscrever acesse: https://lists.nongnu.org/mailman/listinfo/shell-script-pt
Para ver os arquivos da lista (mensagens anteriores) e pesquisar nelas, acesse https://lists.nongnu.org/archive/html/shell-script-pt/

NOTA: A lista anterior, no Yahoo Groups, foi *desativada*. Por favor utilize somente esta.


--
[]'s
Alfredo Tristão Casanova
Linux User #228230



--
[]'s
Alfredo Tristão Casanova
Linux User #228230

_______________________________________________
Lista brasileira de usuários de shell script
Endereço de e-mail da lista: shell-script-pt@nongnu.org
Para se inscrever ou desinscrever acesse: https://lists.nongnu.org/mailman/listinfo/shell-script-pt
Para ver os arquivos da lista (mensagens anteriores) e pesquisar nelas, acesse https://lists.nongnu.org/archive/html/shell-script-pt/

NOTA: A lista anterior, no Yahoo Groups, foi *desativada*. Por favor utilize somente esta.


--
(o_  @arkanon  (Twitter)     __o
//\   arkanon@lsd.org.br   _`\<,
V_/_      www.lsd.org.br  (_)/(_)
---------------------------------

reply via email to

[Prev in Thread] Current Thread [Next in Thread]