Come ottimizzare lo script con NF e un ciclo for

Ho diversi file, ognuno con un diverso numero di colonne. Voglio convertirli per inserirli in un database

Ad esempio il file 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 

Il mio output desiderato è:

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

per ottenere ciò utilizzo il seguente script:

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

E funziona bene, il problema è quando trovo un altro file con un numero diverso di colonne, quindi devo modificare lo script manualmente.

So di poter ottenere il numero di colonne con la variabile NF di AWK, ma come combinare questa variabile con un ciclo for nello script?

Quando provo

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

ottengo questo risultato:

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

Commenti

  • Nel file originale è presente un delimitatore di tabulazione o è solo " alcuni spazi "?
  • È un delimitatore di tabulazione

Risposta

Utilizzo di 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"); 

Il lo script è composto da quattro parti:

  1. s/^/("/ sostituisce linizio della riga con (".
  2. s/\t/","/g sostituisce le tabulazioni con ",". Questo è il bit che richiede GNU sed. Per altre sed implementazioni, inserisci una tabulazione letterale al posto di \t.
  3. s/$/"),/ sostituisce la fine della riga con "),.
  4. $s/.$/;/ sostituisce la virgola alla fine del ultima riga (solo) con ;.

Commenti

  • Eseguo lo script e richiede " > " in attesa di qualcosa
  • @ user3333911 Avevo virgolette non corrispondenti, da una versione precedente. Risolto ora e testato.

Risposta

Se il file di input è separato da tabulazioni, puoi provare quanto segue:

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

Oppure incorpora virgolette nella funzione di stampa:

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

Commenti

  • Guarda le virgole alla fine di tutte le righe tranne lultima …
  • Buona comunicazione @Kusalananda. Ho eseguito una soluzione rapida come in awk -F"\t" -vq="'" -vOFS="','" '$1=$1 {print "(" q $0 q "),"}' filename | sed '$s/,$/;/'. Qualche suggerimento migliore?
  • No, ' è una buona soluzione.

Risposta

Per ottenere lo stesso comportamento che desideri con lo script iniziale puoi utilizzare il metodo “printf” di awk. Rende possibile sbarazzarsi di newline che sono messi da “print”. Immagino che il tuo script dovrebbe essere riscritto in questo modo:

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

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *