Tenho vários arquivos, cada um com um número diferente de colunas. 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 conseguir isso, uso o seguinte script:
cat test01 |awk -F"\t" "{print "("\"""$1""\"","\"""$2""\"","\"""$3""\"","\"""$4""\"","\"""$5""\""),"}" |sed "$ s/.$/;/"
E funciona bem, o problema é quando encontro outro arquivo com um número diferente de colunas, então tenho que modificar o script manualmente.
Eu sei que posso obter o número de colunas com a variável NF do AWK, mas como combinar esta variável com um loop for no script?
Quando tento
cat test01 | awk "{for (i = 1; i <= NF; i++){print $i""\"","\"""}}"
Obtenho 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","
Comentários
- No arquivo original, há um delimitador de tabulação ou apenas " algum espaço em branco "?
- É um delimitador de tabulação
Resposta
Usando 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 o script tem quatro partes:
-
s/^/("/
substitui o início da linha por("
. -
s/\t/","/g
substitui as guias por","
. Este é o bit que requer GNUsed
. Para outrassed
implementações, insira uma guia literal no lugar de\t
. -
s/$/"),/
substitui o final da linha por"),
. -
$s/.$/;/
substitui a vírgula no final do última linha (apenas) com;
.
Comentários
- Eu executo o script e avisa " > " como esperando por algo
- @ user3333911 Eu tinha citações incompatíveis de uma versão anterior. Corrigido agora e testado.
Resposta
Se seu arquivo de entrada for separado por tabulações, você pode tentar o seguinte:
awk -F"\t" -vq=""" -vOFS="","" "$1=$1 {print "(" q $0 q ");"}" filename
Ou incorpore aspas na função de impressão:
awk -F"\t" -vOFS="","" "$1=$1 {print "(" "\x27" $0 "\x27" ");"}" filename
Comentários
- Observe as vírgulas no final de todas as linhas, exceto a última …
- Bom aviso @Kusalananda. Fiz uma correção rápida como em
awk -F"\t" -vq="'" -vOFS="','" '$1=$1 {print "(" q $0 q "),"}' filename | sed '$s/,$/;/'
. Alguma sugestão melhor? - Não, essa ' é uma boa solução.
Resposta
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 se livrar de novas linhas que são colocadas por “imprimir”. Eu estou supondo que seu script deve ser reescrito assim:
cat test01 | awk "{for (i = 1; i <= NF; i++){printf $i""\"","\"""}; printf "\n";}"