|
From: | Julio C. Neves |
Subject: | Re: [shell-script-pt] Fazendo um "de / para" com um cabeçalho CSV |
Date: | Fri, 30 Jul 2021 21:25:36 -0300 |
Prezados colegas de lista:Percebi que precisava ir mais a fundo no conceito de arrays associativos para não perguntar sem ter base para tal.Fiz algum trabalho de leitura e consegui escrever o seguinte código:#!/bin/bash
filecsv="myfile.csv"
# Declara Fields
declare -A Fields
Fields=(
[fname]='First name.string\(\),'
[mname]='Middle name.string\(\),'
[lname]='Last name.string\(\),'
[address]='Address.string\(\),'
[address2]='Address2.string\(\),'
[CITY]='City.string\(\),'
[ST]='state.string\(\),'
[ZIP]='zip.string\(\),'
[SEQ_NUM]='seq_num.int64\(\),'
[CREDIT_DAT]='credit_dat.string\(\),'
[MAIL_DATE]='mail_date.string\(\),'
[MAIL_CLASS]='mail_class.string\(\),'
[EXP_DATE]='exp_date.string\(\),'
[INHOME_DATE]='inhome_date.string\(\),'
[lasercode]='lasercode.string\(\),'
[BATCH_ID]='batch_id.int32\(\),'
[REFCODE]='refcode.string\(\),'
[PURL]='purl.string\(\),'
[PHONE]='phone.string\(\),'
[PKG_NAME]='pkg_name.string\(\),'
[consumerid]='consumerid.int64\(\),'
[age]='age.int32\(\),'
[fico]='fico.int32\(\),'
[open_rev_cnt]='open_rev_cnt.string\(\),'
[utilization]='utilization.int32\(\),'
[debt]='debt.int32\(\),'
);
#Notas
# ${!Fields[@]} = exibe o nome dos elementos no array Fields
# ${Fields[@]} = exibe o valor dos elementos no array Fields
numberFields=${#Fields[@]}
NF=$(awk -F, 'NR==1{print NF}' $filecsv)
declare -A headerFields
for ((i=1;i<=$NF;++i))
do
headerFields[$i]+="$(awk -v VAR=$i -F, 'NR==1{print $VAR}' $filecsv)"
#echo ${headerFields[$i]}
for header in ${headerFields[$i]}
do
arrayHeader=("${arrayHeader[@]}" "$header")
#echo $arrayHeader
done
done
for field in ${!Fields[@]}
do
arrayField=("${!Fields[@]}" "$field")
#echo $arrayField
done
for ((x=0; x<$numberFields; x++))
do
if [[ ${arrayHeader[x]} == ${arrayField[x]} ]]
then
echo "Wright!"
#echo ${arrayHeader[x]}
#echo ${arrayField[x]}
else
echo "wrong!"
#echo ${arrayField[x]}
#echo ${arrayHeader[x]}
#echo "${arrayHeader[x]}-${arrayField[x]}"
fi
done----------------------------------------------------------------------------------------------------------------------------------------------------------myfile.csv:fname,mname,lname,address,address2,CITY,ST,ZIP,SEQ_NUM,CREDIT_DAT,MAIL_DATE,MAIL_CLASS,EXP_DATE,INHOME_DATE,lasercode,BATCH_ID,REFCODE,PURL,PHONE,PKG_NAME,consumerid,age,fico,open_rev_cnt,utilization,debt
Torrence,Lynn,Earl,2219 Cowles St,,Fairbanks,AK,99701-6705,1,06/08/2021,07/22/2021,FIRST,08/27/2021,7/26/2021,SSFD,2,XY0424291,callsafestone.com/torrenceearl5,866-487-5228,D2_SS23_F,38712978,45,519,i: 7+,87,1922Bom, a questão agora é que segundo o excelente artigo do Julio Neves, arrays associativos não são gerados em ordem numérica, logo, entendo eu que o motivo do meu if dar sempre wrong, é que ao comparar ${arrayHeader[x]} com ${arrayField[x]}, acredito qeu sempre será um teste falso, pois não estão em ordem. Fiz um echo para validar isso e ocorre o seguinte:fname-fico
mname-open_rev_cnt
lname-lasercode
address-fname
address2-REFCODE
CITY-utilization
ST-INHOME_DATE
ZIP-PURL
SEQ_NUM-ZIP
CREDIT_DAT-MAIL_DATE
MAIL_DATE-CREDIT_DAT
MAIL_CLASS-PHONE
EXP_DATE-address
INHOME_DATE-CITY
lasercode-MAIL_CLASS
BATCH_ID-lname
REFCODE-BATCH_ID
PURL-debt
PHONE-consumerid
PKG_NAME-age
consumerid-SEQ_NUM
age-EXP_DATE
fico-address2
open_rev_cnt-ST
utilization-PKG_NAME
-mnameEu não saberia dizer se essa ultima linha em vermelho é o único problema ou se a ordem em que ambos aparecem seria também o problema
.Se alguém puder me ajudar a esclarecer.... sigo aqui buscando uma forma de comparar o cabeçalho de um arquivo csv com indices do meu array.Muito obrigado desde sempre!Em qui., 29 de jul. de 2021 às 14:01, George Robinson <george.robinson.br@gmail.com> escreveu:Obs:Relendo mais uma vez o material do Casanova, eu notei que nesse caso, para produzir a saída que eu preciso a estrutura do for deveria ser:for field in "${Fields[*]}" (e não ${!Fields[@]})
do
echo $field
doneEm qui., 29 de jul. de 2021 às 13:47, George Robinson <george.robinson.br@gmail.com> escreveu:Boa tarde amigos!Analisei o material enviado pelos sempre excelentes Alfredo e Julio Neves, e confesso que fico cada vez mais impressionado com o poder do bash para esse tipo de tarefa.Sim, eu sempre tenho algo novo a aprender, me esforço, mas acredito que isso é algo que é necessário sempre buscar mais e mais... Eu consegui, depois de ler e reler N vezes o seguinte resultado:#!/bin/bash
# Declara Fields
declare -A Fields
Fields=(
[fname]='First name'.string\(\)
[mname]='Middle name'.string\(\)
[lname]='Last name'.string\(\)
[address]='Address'.string\(\)
[address2]='Address2'.string\(\)
[CITY]='City'.string\(\)
[ST]='state'.string\(\)
[ZIP]='zip'.string\(\)
[SEQ_NUM]='seq_num'.int64\(\)
[CREDIT_DAT]='credit_dat'.string\(\)
[MAIL_DATE]='mail_date'.string\(\)
[MAIL_CLASS]='mail_class'.string\(\)
[EXP_DATE]='exp_date'.string\(\)
[INHOME_DATE]='inhome_date'.string\(\)
[lasercode]='lasercode'.string\(\)
[BATCH_ID]='batch_id'.int32\(\)
[REFCODE]='refcode'.string\(\)
[PURL]='purl'.string\(\)
[PHONE]='phone'.string\(\)
[PKG_NAME]='pkg_name'.string\(\)
[consumerid]='consumerid'.int64\(\)
[age]='age'.int32\(\)
[fico]='fico'.int32\(\)
[open_rev_cnt]='open_rev_cnt'.string\(\)
[utilization]='utilization'.int32\(\)
[debt]='debt'.int32\(\)
);
for field in "${!Fields[@]}"
do
Value=("${Fields[@]}" "${field[@]}")
done
echo ${Value[@]}----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------Que produz a seguinte saída:fico.int32() open_rev_cnt.string() lasercode.string() First name.string() refcode.string() utilization.int32() inhome_date.string() purl.string() zip.string() mail_date.string() credit_dat.string() phone.string() Address.string() City.string() mail_class.string() Last name.string() batch_id.int32() debt.int32() consumerid.int64() age.int32() seq_num.int64() exp_date.string() Address2.string() state.string() pkg_name.string() Middle name.string() mnameQue aredito eu que é baseado no índice mname.Até aqui, vi que é possível gerar o valor do vetor de acordo com o índice, se eu nao estou enganado, esse resultado é um elemento único. Como eu cheguei a essa conclusão? S eu colocar o echo dentro do FOR, ele vai produzir a mesma saída para cada um dos 25 elementos do array FIELDS.Entendo que para efeitos de comparação com o arquivo myfile.csv que possui o seguinte cabeçalho:( fname,mname,lname,address,address2,CITY,ST,ZIP,SEQ_NUM,CREDIT_DAT,MAIL_DATE,MAIL_CLASS,EXP_DATE,INHOME_DATE,lasercode,BATCH_ID,REFCODE,PURL,PHONE,PKG_NAME,consumerid,age,fico,open_rev_cnt,utilization,debt)eu acredito que estaria tentando comparar toda a saída do echo com cada um dos elementos do arquivo.csv.Estaria eu enganado?Atenciosamente,Em qui., 29 de jul. de 2021 às 09:05, Julio C. Neves <julio.neves@gmail.com> escreveu:Bom dia George,não sei se entendi direito o seu problema, mas o Bash possui recursos de vetores associativos (arrays com índice alfanumérico) e tão logo esse recurso foi incorporado ao Bash, escrevi um artigo básico sobre esta técnica que está em http://www.dicas-l.com.br/cantinhodoshell/cantinhodoshell_20100120.php#.YQKYNHVKjb0Abraços,Julio» Não tem tempo para fazer um curso presencial?» Na sua cidade não tem nenhum bom curso de Linux?Veja detalhes em: https://www.dicas-l.com.br/educacao/programacao-shell-linux/Também damos treinamento em sua empresaem qualquer cidade, com certificado e nota fiscal._______________________________________________Em qua., 28 de jul. de 2021 às 20:24, George Robinson <george.robinson.br@gmail.com> escreveu:_______________________________________________Prezados, boa noite!Montei um pequeno script em shell que faz a leitura de um cabeçalho CSV e os insere em um banco de dados com a seguinte estrutura:Cabeçalho CSV:fname,mname,lname,address,address2,CITY,ST,ZIP,SEQ_NUMWilliam,Dias,Maranhão,Rua Khalifa,Casa 03,Paraty,RJ,24444-444,1neste caso, o que eu faço no meu script é pegar cada campo e assumir que a sequencia do arquivo sempre será essa. Então quando eu faço um import no banco seria algo assim:mongoimport -h localhost:27017 -u $mobilendPrdUser -p $mobilendPasswd\
--db $mobilendPrdDb \
--collection $collection \
--type csv \
--columnsHaveTypes \
--fields 'First name'.string\(\),'Middle name'.string\(\),'Last name'.string\(\),'Address'.string\(\),'Address2'.string\(\),'City'.string\(\),'state'.string\(\),'zip'.string\(\),'seq_num'.int64\(\)Porém, notei, que em alguns casos, o cabeçalho que recebo para dar carga no banco pode mudar, podendo ter mais campos à esquerda ou a direita. Sendo assim, o cabeçalhofname,mname,lname,address,address2,CITY,ST,ZIP,SEQ_NUM pode passar a seremail,id,fname,mname,lname,address,address2,CITY,ST,ZIP,SEQ_NUM,phone,etc ou até mesmo mudança na nomenclatura do cabeçalho (fname, passando a ser first name)eu gostaria de ter algo como um array contendo todas as possibilidades como por exemplo (fiz em python)dataTypes = {}dataTypes["fname"] = "string"
dataTypes["firstname"] = "string"
dataTypes["first name"] = "string"dataTypes["mname"] = "string"
dataTypes["middlename"] = "string"
dataTypes["middle name"] = "string"dataTypes["lname"] = "string"
dataTypes["lastname"] = "string"
dataTypes["last name"] = "string"dataTypes["address"] = "string"dataTypes["address2"] = "string"dataTypes["city"] = "string"dataTypes["st"] = "string"dataTypes["state"] = "string"dataTypes["zip"] = "string"dataTypes["seq_number"] = "int64"
dataTypes["phone"] = "string"
dataTypes["phonenumber"] = "string"
dataTypes["phone number"] = "string"A ideia seria ter um "índice" de possíveis campos de cabeçalho e "mapeá-los" de acordo com o que recebo no arquivo, já definindo o dataType dele.Hoje meu script segue uma sequência presumida, que se quebrada, insere os campos fora de posição na tabela, o que me força a atualzar o script para bater com a sequencia recebida.Se alguém puder me ajudar, acho que só falta essa parte pra ele ficar bem automatizado.--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.
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
--George Robinson
Analista de Suporte
Tel: +55 (21) 97449-8138
--_______________________________________________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.
[Prev in Thread] | Current Thread | [Next in Thread] |