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

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

Re: [shell-script-pt] Usando while... do e If no mesmo pipe


From: George Robinson
Subject: Re: [shell-script-pt] Usando while... do e If no mesmo pipe
Date: Fri, 11 Dec 2020 22:17:13 -0300

Olá Arkanon!!!

Olha, eu realmente não sei como agradecer pela aula. Você não apenas me ajudou, respondendo perfeitamente ao meu questionamento, mas vc explicou em detalhes o processo.

Pra falar a verdade, eu até achei que o problema persistia, mas observando com calma, há ainda uma questão. Enquanto o contratado ainda não foi efetivado na empresa, as duplicadas ocorrem até que ele seja cadastrado e entre na base, o que não é de forma alguma um problema, pois acredito que o processo de admissão seja feito no dia seguinte à sua inserção na fila de admissão (visto que o script rodará às 00:00).

Quero destacar e agradecer pelas formas diferentes que o mesmo objetivo pode ser alcançado, e de novo, vc me deu uma nova aula sobre KISS (keep it simple stupid! :D)

É incrível como o shell é simples e poderoso e sinceramente, definitivamente shell tem um lugar no mundo onde nenhum marketing agressivo conseguirá tirar!

Atenciosamente,

Em sex., 11 de dez. de 2020 às 21:08, Arkanon <arkanon@lsd.org.br> escreveu:
Beleza, George?

Legal ver teu script avançando :)

A função checkCpf está retornando "coisas" além do que quer que seja que deveria estar retornando. Observe que ela começa retornando "\n$1". $1 é o cpf a ser checado , então ela
  • retorna "\n" (line feed, quebra de linha) que no caso significa uma linha em branco,
  • depois o cpf que foi dado como parâmetro.
  • depois retorna o resultado do curl processado pelo jq (que precisa de uns trabalhinhos ainda até funcionar) E
  • depois retorna outro line feed.
Depois você compara tudo isso com o número puro do cpf. Não tem como ser igual :-p

Se seu único objetivo é identificar com base no cpf se o registro que está para ser incluído já está na base, pode tentar trocar a atribuição da variável check com o resultado da função checkCpf por um simples grep no resultado do curl sem processamento algum com o jq.

curl -s -X GET -H token:${token[BLUIP]} $urlCPFemployees | grep --color -i cpf
{"message":"","data":[{"id":"a8314e2e-88c9-44d0-8129-11925044a87e","name":"George","last_name":"Robinson da Silva Serejo Santos","email":"george.serejo@blu.com.br","documents":{"pis":null,"cpf":"10235233706"},"hiring_date":"2020-12-01"},{"id":"ea9a4477-74db-43c4-9d25-33b08350171a","name":"Jonas","last_name":"Fake","email":"jonas.fake@mycompany.com","documents":{"pis":null,"cpf":null},"hiring_date":"2019-08-11"}],"redirect":null,"success":true}

Há dois campos chamados "cpf". Nesse exemplo apenas um está "preenchido". Veja se é suficiente simplesmente testar se existe a ocorrência do número do cpf neste json. Se sim, seu teste pode se resumir a:

curl -s -X GET -H token:${token[BLUIP]} $urlCPFemployees | grep -q $cpf || api $empresa "hiring_date=$dataContratacao&name=$nome&last_name=$sobrenome&documents[cpf]=$cpf&job=$cargo&department=$departamento&cell=$telefone&email=$email&supervisor[name]=$gestorNome&salary=$salario"

Basicamente, a linha acima "grepa" o resultado do curl à procura de $cpf. Se NÃO casar, aí chama a api para inserir (imagino que é o que será feito).

O --color no primeiro exemplo foi usado para facilitar a visualização no terminal. Eu pesquisei pela string "cpf", não pelo número de um cpf. Fiz isso para ver onde, como e quantas vezes aparecia um campo relacionado com cpf. Por isso também fiz uma pesquisa case insensitive (-i).

No segundo exemplo, que é a linha que iria para o script, usei o -q, para o grep não devolver nada para a tela. Dessa forma, ele apenas testa se casou e eu posso usá-lo de forma limpa para tomar uma decisão, no caso, relativa apenas ao senão: existe o cpf? Senão existe (||), então inclui. É um if sem then, MUITO usado em shell script. Poderia fazer assim:

if curl ... | grep -q ...
then
  :
else
  api ...
fi

Mas da forma sugerida é mais sintético (:
Os dois pontos são usados quando nada deve ser feito. Não colocar nada ou colcoar apenas um comentário não é suficiente, e um echo não é do interesse no momento.
Aliás, como o Mestre Julio sempre ressalta: o if do shell NÃO TESTA condição. Testa INSTRUÇÃO. Qualquer comando pode ser testado para uma tomada de uma decisão em cima do sucesso de sua finalização.

Att,

Em sex., 11 de dez. de 2020 às 20:06, George Robinson <george.robinson.br@gmail.com> escreveu:
Prezados,

Estou aqui tentando criar uma "melhoria" no script no qual recebi grande ajuda dias atrás. Ele consiste em validar se um determinado CPF existe na base de dados para que não sejam criados dois cadastros no sistema, porém, estou enfrentando dificuldades, pois não saberia dizer onde está o erro no script abaixo:

myCompanyOutput.txt:
2020-09-08,Wellison,Souza,40255489846,Desenvolvedor,Tecnologia da Informação,11977227508,wellison28@gmail.com,Saulo Da Silva Santiago,8000,BLUIP
2020-12-07,Vinícius,Camargo,36843664806,Analista de Marketing,Marketing,48991422409,vh.camargo88@gmail.com,Jonas Fake,5500,BLUIP
2020-11-16,Rodrigo,Marafelli,12487916656,Desenvolvedor,Desenvolvimento,35988835248,marafellirodrigo@gmail.com,Eduardo Fiorezi,3000,BLUIP
2020-12-01,Guilherme,Rosa,08822812751,Gerente de Remuneração e Benefícios,Gente & Gestão,21976748288,guilherme_rosa@me.com,João Guilherme Barbosa de Amorim,16000,BLUIP
2020-12-11,Leandro,Viegas,15080398795,Analista de BI,BI,21972862837,leandro.trab18@hotmail.com,Thiago Patente,5000,BLUIP

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
cadastraDados:

urlCPFemployees=https://public-api.convenia.com.br/api/v3/employees ; \
url="" href="https://public-api.convenia.com.br/api/v3/employees/admission" target="_blank">https://public-api.convenia.com.br/api/v3/employees/admission; \
declare -A token \
token=( \
[BLUIP]=81ca6848-a745-4050-bac7-9ffb7d860a95 \
[myCompany02]=7b541570-16eb-4468-a222-f7789e1cfff9 \
[myCompany03]=0337304e-1d8f-4252-8676-9eb73c28393e \
); \
checkCpf() { echo -e "\n$1"; curl --request GET -H token:${token[$1]} $urlCPFemployees | jq -r '.data[].documents | select (.cpf!=null)' | jq -r '. | select (.cpf (match("'"$cpf"'")))'; echo; }; \
api() { echo -e "\n$1"; curl -s -X POST -H token:${token[$1]} -d "$2" $url; echo; }; \
while IFS=, read dataContratacao nome sobrenome cpf cargo departamento telefone email gestorNome salario empresa ; \
do \
\
check=`checkCpf $cpf` ; \
\
if [[ $check != $cpf ]] ; \
then \
api $empresa "hiring_date=$dataContratacao&name=$nome&last_name=$sobrenome&documents[cpf]=$cpf&job=$cargo&department=$departamento&cell=$telefone&email=$email&supervisor[name]=$gestorNome&salary=$salario" ; \
\
fi; \
done < myCompanyOutput.txt
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Sim, há erros de sintaxe, porém, o que eu estou tentando entender é qual seria a melhor forma de enviar o cadastro apenas se não houver o CPF em questão já registrado.

PS: Esse é um sistema de testes, portanto, não há problemas em enviar os testes para a API :)



Em sex., 20 de nov. de 2020 às 10:09, Arkanon <arkanon@lsd.org.br> escreveu:
"Eu nem tinha isso como objetivo profissional, e aos poucos o shell tem se mostrado mais eficiente e simples do que outras linguagens que tenho tentado aprender."

Não precisa dizer mais nada, George. Uma galera aqui (eu incluído!) já ganhou o dia só com esse reconhecimento de alguém que muito provavelmente está se entregando à cachaça que é a programação em shell script! :D

Em sex., 20 de nov. de 2020 às 09:47, George Robinson <george.robinson.br@gmail.com> escreveu:
Olá!

Gostaria de agradecer a todos pela grandiosa aula que recebi. Quanto à indentação do código, o que aconteceu é que eu já havia feito antes, porém, estava errado, então uni tudo e mandei o comando. Eu peço desculpas pela deselegância (isto sim é feio, se é pra escrever, vamos escrever direito!), porém, eu já estava há muitas horas batendo cabeça, e não sou nenhum pouco avançado no assunto e portanto, coisas elementares como elegância de código, reaproveitamento de um array, realmente eu acabei deixando feito e sujo.

Arkanon, Julio e Paulo,

Obrigado pelo sempre interesse em ajudar, e saibam que essas coisas mudam vidas. Eu nem tinha isso como objetivo profissional, e aos poucos o shell tem se mostrado mais eficiente e simples do que outras linguagens que tenho tentado aprender.

Mais uma vez, obrigado por isso!

Em sex., 20 de nov. de 2020 às 05:16, Arkanon <arkanon@lsd.org.br> escreveu:
Beleza, George?

Anote essa sugestão do Mestre Julio: apresente sempre seu código da forma mais legível possível. Vai ajudar não apenas os integrantes da lista a entenderem seu algoritmo, mas principalmente você, que provavelmente será o responsável pela manutenção futura dele :-)

Se eu copiei e colei corretamente o código original, identando-o segundo algum critério discutível chegamos a algo assim:

cat << EOT > myCompanyOutput.txt
2020-12-01,Guilherme,Rosa,08822812751,Gerente de Remuneração e Benefícios,Tecnologia da Informação,21976748288,guilherme_rosa@me.com,Jonas Fake,16000,myCompany
2020-12-08,George Robinson,da Silva Serejo Santos,10235233706,Analista de Suporte Sênior,Tecnologia da Informação,21974498138,george.robinson.br@gmail.com,Jonas Fake,16000,myCompany02
2020-12-15,Rosilene,Barbosa de Souza,11271238748,Analista de Marketing,Marketing,21966724094,rosilenebs30@gmail.com,Jonas Fake,16000,myCompany03
EOT

cat myCompanyOutput.txt \
| while IFS=, read hiringDate name last_name cpf cargo departamento telefone email gestorName salary empresa
  do
    if [[ $empresa == myCompany ]]
    then
      curl -s \
        -X POST \
        -H accept:application/json \
        -H token:f5ca4c9f-a530-48e5-ac8c-cf33cf5b74b1 \
        -d "hiring_date=$hiringDate&name=$name&last_name=$last_name&documents[cpf]=$cpf&job=$cargo&cell=$telefone&email=$email&supervisor[name]=$gestorName&department=$departamento&salary=$salary" \
        https://public-api.convenia.com.br/api/v3/employees/admission \
      | if [[ $empresa == myCompany02 ]]
        then
          curl -s \
            -X POST \
            -H accept:application/json \
            -H token:7b541570-16eb-4468-a222-f7789e1cfff9 \
            -d "hiring_date=$hiringDate&name=$name&last_name=$last_name&documents[cpf]=$cpf&job=$cargo&cell=$telefone&email=$email&supervisor[name]=$gestorName&department=$departamento&salary=$salary" \
            https://public-api.convenia.com.br/api/v3/employees/admission \
          | if [[ $empresa == myCompany03 ]]
            then
              curl -s \
                -X POST \
                -H accept:application/json \
                -H token:0337304e-1d8f-4252-8676-9eb73c28393e \
                -d "hiring_date=$hiringDate&name=$name&last_name=$last_name&documents[cpf]=$cpf&job=$cargo&cell=$telefone&email=$email&supervisor[name]=$gestorName&department=$departamento&salary=$salary" \
                https://public-api.convenia.com.br/api/v3/employees/admission
            fi
        fi
    fi
  done


Já corrigi o erro de sintaxe apontado pelo Julio.
Também adicionei pequenas alterações na sintaxe dos comandos curl para deixá-los um pouco mais alinhados, mas nada que não funcionasse na sua versão original.

Achei um tanto estranho esse encadeamento de if curl com pipes. Não parece que vá funcionar, como podemos verificar executando o código. Você disse num outro email que já o corrigiu, talvez tenha trocado os pipes por ponto e vírgula, não sei.

Agora, assumindo que o que você tem no while são três testes para executar a chamada da api via curl conforme a empresa, cada uma com seu próprio token, deixo uma sugestão de código que parece ser equivalente e que detalho na sequência:

# 1
url="" href="https://public-api.convenia.com.br/api/v3/employees/admission" target="_blank">https://public-api.convenia.com.br/api/v3/employees/admission

# 2
declare -A token
token=(
          [myCompany]=f5ca4c9f-a530-48e5-ac8c-cf33cf5b74b1
        [myCompany02]=7b541570-16eb-4468-a222-f7789e1cfff9
        [myCompany03]=0337304e-1d8f-4252-8676-9eb73c28393e
      )

# 3
api() { echo -e "\n$1"; curl -s -X POST -H accept:application/json -H token:${token[$1]} -d "$2" $url; echo; }

# 4
while IFS=, read hiringDate name last_name cpf cargo departamento telefone email gestorName salary empresa
do
  api $empresa "hiring_date=$hiringDate&name=$name&last_name=$last_name&documents[cpf]=$cpf&job=$cargo&cell=$telefone&email=$email&supervisor[name]=$gestorName&department=$departamento&salary=$salary"
done < myCompanyOutput.txt
  1. começamos armazenando a url da api em uma variável, já que ela é a mesma em todas as chamadas.
  2. se em cada laço do loop temos apenas uma empresa, cada uma com seu token, e para cada uma delas é feito um teste para chamar a api usando esse token, então, um array associativo onde os índices são os nomes das empresas apontando para seu respectivo token permite recuperar essa informação em cada laço do loop sem executar teste algum.
  3. como o Paulo bem observou na resposta dele, a única diferença entre as chamadas da api são os tokens. Isso sugere fortemente a substituição de todos os comandos curl por alguma função que abstraia tudo o que há em comum, passando como parâmetro apenas o que difere. Essa é a função da função api :-p Pode ver que ela recebe dois parâmetros: $1, com o token e $2, com os dados passados para a api rest propriamente dita. Aliás, pelo menos com esses dados que você passou, o parâmetro de header -H accept:application/json é desnecessário. A chamada funciona perfeitamente sem ele. Você pode muito bem usar a função:
    api() { echo -e "\n$1"; curl -s -X POST -H token:${token[$1]} -d "$2" $url; echo; }
  4. finalmente, iteramos sobre as linhas do arquivo myCompanyOutput.txt, em cada laço passando para a função api o nome da empresa (que será usado na função para recuperar o token armazenado no array associativo) e os dados montados para uso na chamada da api. Observe a forma como o arquivo é lido: ao invés de usar um cat criando um subshell para passar os dados via pipe, simplesmente é feito um redirecionamento do arquivo para o while. Mais simples e eficiente.
  5. alguém poderia sugerir que, uma vez que agora há apenas UM comando curl (o que está na função api), a variável $url poderia ser dispensada colocando seu valor diretamente na chamada do comando dentro da função. Bom, não é uma boa prática chumbar parâmetros, mesmo quando cumprem função de constantes ou aparecem apenas uma vez.
Executando o código, recebemos:

myCompany
{"message":"","data":[{"id":"468b3e42-0948-4c15-8a4c-f4a436813eaa","status":0,"employee":{"id":"debc67f9-8741-4dd8-ac49-b7029323fae9", ... ,"redirect":null,"success":true}

myCompany02
{"message":"","data":[{"id":"d614e833-410b-43ad-b9d9-88617898cb1e","status":0,"employee":{"id":"23f0fe3c-8afe-426b-b459-e62af809ad61", ... ,"redirect":null,"success":true}

myCompany03
{"message":"","data":[{"id":"35754717-7dc5-47d7-aa40-02bb8acb25ba","status":0,"employee":{"id":"64c2c8ea-324d-499a-ac0e-6e782c3b731e", ... ,"redirect":null,"success":true}

Parece correto, olhando o valor do campo success no json de retorno.

Att,

Em qui., 19 de nov. de 2020 às 18:11, George Robinson <george.robinson.br@gmail.com> escreveu:
Prezada lista,

Estou tentando fazer uma leitura em um arquivo .txt e de acordo com o campo que vou ler (identificação da empresa), fazer um cadastro usando cURL via API. Eu tenho a seguinte entrada e a seguinte saída:

cat myCompanyOutput.txt | while IFS=, read hiringDate name last_name cpf cargo departamento telefone email gestorName salary empresa; do if [[$empresa=='myCompany']] ; then curl  -X POST --url "https://public-api.convenia.com.br/api/v3/employees/admission" --header 'Accept: application/json' --header 'token: f5ca4c9f-a530-48e5-ac8c-cf33cf5b74b1' -d "hiring_date=$hiringDate&name=$name&last_name=$last_name&documents[cpf]=$cpf&job=$cargo&cell=$telefone&email=$email&supervisor[name]=$gestorName&department=$departamento&salary=$salary"| if [[$empresa=='myCompany02']] ; then curl -X POST --url "https://public-api.convenia.com.br/api/v3/employees/admission" --header 'Accept: application/json' --header 'token: 7b541570-16eb-4468-a222-f7789e1cfff9' -d "hiring_date=$hiringDate&name=$name&last_name=$last_name&documents[cpf]=$cpf&job=$cargo&cell=$telefone&email=$email&supervisor[name]=$gestorName&department=$departamento&salary=$salary" | if [[$empresa=='myCompany03']]; then curl  -X POST --url "https://public-api.convenia.com.br/api/v3/employees/admission" --header 'Accept: application/json' --header 'token:  0337304e-1d8f-4252-8676-9eb73c28393e' -d "hiring_date=$hiringDate&name=$name&last_name=$last_name&documents[cpf]=$cpf&job=$cargo&cell=$telefone&email=$email&supervisor[name]=$gestorName&department=$departamento&salary=$salary"; fi;fi;fi; done

SAÍDA:
bash: [[myCompany==myCompany]]: comando não encontrado
bash: [[myCompany02==myCompany]]: comando não encontrado
bash: [[myCompany03==myCompany]]: comando não encontrado

Conteúdo do arquivo myCompanyOutput:
2020-12-01,Guilherme,Rosa,08822812751,Gerente de Remuneração e Benefícios,Tecnologia da Informação,21976748288,guilherme_rosa@me.com,Jonas Fake,16000,myCompany
2020-12-08,George Robinson,da Silva Serejo Santos,10235233706,Analista de Suporte Sênior,Tecnologia da Informação,21974498138,george.robinson.br@gmail.com,Jonas Fake,16000,myCompany02
2020-12-15,Rosilene,Barbosa de Souza,11271238748,Analista de Marketing,Marketing,21966724094,rosilenebs30@gmail.com,Jonas Fake,16000,myCompany03

O caminho seria realmente criar uma confição IF de acordo com o campo que representa a empresa?

Atenciosamente,

--
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  (_)/(_)
---------------------------------
_______________________________________________
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  (_)/(_)
---------------------------------
_______________________________________________
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

reply via email to

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