Solucionado (ver solução)
Solucionado
(ver solução)
5
respostas

como ler dois arquivos usando chave do arquivo lido

Boa tarde pessoal, estou com uma duvida tenho dois arquivo. arquivo Pessoa e arquivo Pertences

Preciso encontrar todos os pertences de uma pessoa.

então para cada registros de pessoa buscar os seus pertences.

pensei em fazer com awk, mas sem sucesso. se alguem puder me ajudar serei muito grato!

5 respostas

Como os arquivos estão organizados? É um CSV?

Pode colar aqui algumas linhas de cada um, pra que a gente possa ter uma idéia melhor de como resolver seu caso?

Fala Marcos, obrigado pelo retorno segue mais detalhes.

o arquivo esta em csv e delimitado por pipe.

Arquivo Pessoa

nome|campo2|campo3
Tiago|campo2|campo3
Rogerio|campo2|campo3
Andre|campo2|campo3

Arquivo Pertence

nome|pertence
Tiago|celular
Tiago|relogio
Rogerio|bicicleta

a tabela de saida do batimento seria

Tiago|campo2|campo3|celular
Tiago|campo2|campo3|relogio
Rogerio|campo2|campo3|celular

Marcos esse é um exemplo o nome seria o id. preciso gerar uma terceira tabela que a saida seria o cruzamento.

solução!

Fala Tiagos. Não fiz esse curso então não sei bem o que ele aborda, mas posso dar uma solução pra você. O passo a passo seria:

  1. ler e armazenar em memória a lista de pertences
  2. ler a lista de pessoas e, pra cada pessoa, conferir a lista de pertences
  3. se o pertence for da pessoa, armazenar isso no arquivo final

Opcional: adicionar ou remover o cabeçalho.

O código abaixo vai fazer exatamente isso que eu te falei, usando as seguintes técnicas:

  • declaração de array e armazenamento
  • loop while pra ler cada arquivo (precisa ter uma linha final vazia)
  • awk para separação de campos (opção -F pra substituir o delimitador padrão espaço por pipe)
  • sed para fazer uma substituição imediata de string e armazenar em uma variável, com a opção -e para usar expressão regular
  • echo com redirecionamento de saída >> para concatenar ao arquivo de saída
#!/bin/bash

# lista de pertences (pra não ler do arquivo n vezes)
pertences=()

#_header=true
while read _line; do
  #[ $_header == true ] && _header=false && continue

  pertences+=("$_line")
done < pertence.psv

#_header=true
while read _pessoa; do
  #[ $_header == true ] && _header=false && continue

  # pega o campo "nome" da pessoa
  _pessoaNome=$(echo $_pessoa | awk -F  '|' '{print $1}')
  # pega os "campos extras" da pessoa
  _pessoaCampos=$(echo $_pessoa | sed -e 's/'$_pessoaNome'|//g')

  # pra cada item na lista de pertences
  for _pertence in ${pertences[*]}; do
    # pega o campo "nome" do pertence
    _pertenceNome=$(echo $_pertence | awk -F  '|' '{print $1}')

    # se os nomes forem iguais,
    if [ "$_pertenceNome" == "$_pessoaNome" ]; then
      # pega o campo "pertence"
      _pertenceObjeto=$(echo $_pertence | awk -F  '|' '{print $2}')
      # concatena tudo numa nova linha do arquivo de saida
      echo "$_pessoaNome|$_pessoaCampos|$_pertenceObjeto" >> saida.psv
    fi
  done
done < pessoa.psv

A saída desse código fica algo assim:

nome|campo2|campo3|pertence
Tiago|campo2|campo3|celular
Tiago|campo2|campo3|relogio
Rogerio|campo2|campo3|bicicleta

Se você quiser ignorar os cabeçalhos (e não imprimi-los no arquivo de saída) basta DEScomentar as linhas entre os dois whiles que utilizam a variável _header.

É isso! Qualquer dúvida manda um toque aqui!

Ps.: essa solução é simplificada pois espera que:

  1. ambos os arquivos tenham cabeçalho
  2. que os campos de id sejam sempre os primeiros
  3. os campos extra sempre existam (mesmo que vazios, como em Tiago|valor2||valor4)
  4. que os arquivos de leitura estejam na pasta de onde é executado o script

Muito obrigado meu amigo Marco Salles. muito bem explicado e detalhado. nota mil!

Estamos aí pra isso =)

Qualquer coisa é só chamar.