Como otimizar o script com NF e um loop for

4

Eu tenho vários arquivos, cada um com um número diferente de colunas. Eu quero convertê-los para inseri-los em um banco de dados

Por exemplo, o arquivo test01:

0001    000000000000001 john smith  45  500
0002    000000000000002 peter jackson   20  80
0003    000000000000002 robert brown    35  100
0004    000000000000007 sarah white 40  300

Minha saída desejada é:

('0001','000000000000001','john smith','45','500'),
('0002','000000000000002','peter jackson','20','80'),
('0003','000000000000002','robert brown','35','100'),
('0004','000000000000007','sarah white','40','300');

para achive isso eu uso o seguinte script:

cat test01 |awk -F'\t' '{print "('\''"$1"'\'','\''"$2"'\'','\''"$3"'\'','\''"$4"'\'','\''"$5"'\''),"}' |sed '$ s/.$/;/' 

E funciona bem, o problema é quando eu encontro outro arquivo com um número diferente de colunas, então eu tenho que modificar o script manualmente.

Eu sei que posso obter o número da coluna com a variável NF do AWK, mas como combinar essa variável com um loop for no script?

Quando eu tento

cat test01 | awk '{for (i = 1; i <= NF; i++){print $i"'\'','\''"}}'

Eu recebo este resultado:

0001','
000000000000001','
john','
smith','
45','
500','
0002','
000000000000002','
peter','
jackson','
20','
80','
0003','
000000000000002','
robert','
brown','
35','
100','
0004','
000000000000007','
sarah','
white','
40','
300','
    
por Emilio Galarraga 03.09.2017 / 16:06

3 respostas

4

Usando o GNU sed :

$ sed -e "s/^/('/" -e "s/\t/','/g" -e "s/$/'),/" -e '$s/.$/;/' file
('0001','000000000000001','john smith','45','500'),
('0002','000000000000002','peter jackson','20','80'),
('0003','000000000000002','robert brown','35','100'),
('0004','000000000000007','sarah white','40','300');

O script sed está dividido em quatro partes:

  1. s/^/('/ substitui o início da linha por (' .
  2. s/\t/','/g substitui tabulações por ',' . Este é o bit que requer o GNU sed . Para outras implementações de sed , insira uma guia literal no lugar de \t .
  3. s/$/'),/ substitui o fim da linha por '), .
  4. $s/.$/;/ substitui a vírgula no final da última linha (somente) com ; .
por 03.09.2017 / 16:26
5

Se o seu arquivo de entrada estiver separado por tabulações, você pode tentar o seguinte:

awk -F"\t" -vq="'" -vOFS="','" '$1=$1 {print "(" q $0 q ");"}' filename

Ou incorpore cotações na função de impressão:

awk -F"\t" -vOFS="','" '$1=$1 {print "(" "\x27" $0 "\x27" ");"}' filename
    
por 03.09.2017 / 16:42
0

Para alcançar o mesmo comportamento que você deseja com seu script inicial, você pode usar o método "printf" do awk. Torna possível livrar-se de novas linhas que são colocadas por "imprimir". Eu estou supondo, seu script deve ser reescrito assim:

cat test01 | awk '{for (i = 1; i <= NF; i++){printf $i"'\'','\''"}; printf "\n";}'
    
por 03.04.2018 / 11:11

Tags