extrai dados de arquivos de texto para csv

1

Eu tenho uma série de arquivos de texto com um formato consistente como:

FirstName: Mary
LastName: Smith
Address: 123 Anywhere St
City: Nowhere
State: TX
Zip: 77777

Eu preciso extrair várias linhas desses arquivos e enviá-los em um arquivo csv em um formato como:

<filename>,<FirstName>,<City>,<Zip>

Eu posso obter os campos que quero com um simples grep, mas não sei como obter a saída da maneira que preciso.

    
por Kevin Pearce 08.08.2016 / 23:07

3 respostas

0

Se você tiver apenas um registro por arquivo, então este é um loop de leitura simples.

#!/bin/bash

read_data()
{
  local first last addr city state zip

  file=$1

  while read -r header data
  do
    case $header in
      FirstName:) first=$data ;;
       LastName:) last=$data ;;
        Address:) addr=$data ;;
           City:) city=$data ;;
          State:) state=$data ;;
            Zip:) zip=$data ;;
               *) echo Ignoring bad line $header $data >&2
    esac
  done < $file
  echo "$file,$first,$last,$addr,$city,$state,$zip"
}

for file in *srcfiles*
do
  read_data $file
done

A função read_data lê cada linha e divide a linha em um "cabeçalho" e um "dado". Quando chegamos ao final do arquivo, acabamos de imprimir os resultados.

Chamamos essa função uma vez para cada arquivo de origem por meio do loop for .

Observe algumas pegadinhas em potencial: se houver vírgulas nos dados, isso quebrará as coisas, então você pode querer fazer

  echo "\"$file\",\"$first\",\"$last\",\"$addr\",\"$city\",\"$state\",\"$zip\""

como saída para incluir tudo dentro do layout "..." . Se houver qualquer " nos dados, isso poderá fazer com que o CSV também seja malformado.

Ajuste a linha echo para corresponder ao formato desejado.

    
por 09.08.2016 / 00:09
0

Abordagem rápida e suja, pode atender às suas necessidades.

grep . *|perl -ne 'if(/FirstName: (.*)/){$f=$1}if(/City: (.*)/){$c=$1}if(/^(.*):Zip: (.*)/){print "$1,$f,$c,$2\n"}'

Exemplo:

grep . *
f1.txt:FirstName: Mary
f1.txt:LastName: Smith
f1.txt:Address: 123 Anywhere St
f1.txt:City: Nowhere
f1.txt:State: TX
f1.txt:Zip: 77777
f2.txt:FirstName: Joe
f2.txt:LastName: Bloggs
f2.txt:Address: 444 Anywhere St
f2.txt:City: Nowhere2
f2.txt:State: TXA
f2.txt:Zip: 77737
grep . *|perl -ne 'if(/FirstName: (.*)/){$f=$1}if(/City: (.*)/){$c=$1}if(/^(.*):Zip: (.*)/){print "$1,$f,$c,$2\n"}'
f1.txt,Mary,Nowhere,77777
f2.txt,Joe,Nowhere2,77737
    
por 09.08.2016 / 00:10
0

Se houver um único registro por arquivo e você tiver o GNU awk, você pode fazer

gawk -F': +' -vOFS=, '
  BEGINFILE{delete rec}
  {rec[$1] = $2}
  ENDFILE{print FILENAME, rec["FirstName"], rec["City"], rec["Zip"]}
' file1.txt file2.txt ...
    
por 09.08.2016 / 00:29