Hvordan optimalisere skript med NF og a for loop

Jeg har flere filer, hver med forskjellig antall kolonner. Jeg vil konvertere dem for å sette dem inn i en database

For eksempel filen 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 

Min ønskede utgang er:

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

for å oppnå dette bruker jeg følgende skript:

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

Og det fungerer fint, problemet er når jeg finner en annen fil med et annet antall kolonner, så jeg må endre skriptet manuelt.

Jeg vet at jeg kan få antall kolonner med AWKs variabel NF, men hvordan å kombinere denne variabelen med en for loop i skriptet?

Når jeg prøver

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

får jeg dette resultatet:

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

Kommentarer

  • I originalfilen er det en tabulatoravgrenser, eller er det bare " noe mellomrom "?
  • Det er en tabulatoravgrenser

Svar

Bruk 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"); 

skript er i fire deler:

  1. s/^/("/ erstatter start på linje med (".
  2. s/\t/","/g erstatter faner med ",". Dette er biten som krever GNU sed. For andre sed implementeringer, sett inn en bokstavelig fane i stedet for \t.
  3. s/$/"),/ erstatter slutten av linjen med "),.
  4. $s/.$/;/ erstatter kommaet på slutten av siste linje (bare) med ;.

Kommentarer

  • Jeg kjører skriptet og den ber " > " som forventet om noe
  • @ user3333911 Jeg hadde ikke samsvarende sitater fra en tidligere versjon. Fikset nå, og testet.

Svar

Hvis inndatafilen din er tabulatoradskilt, kan du prøve følgende:

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

Eller legg inn anførselstegn i utskriftsfunksjonen:

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

Kommentarer

  • Se kommaene på slutten av alle linjene, bortsett fra den siste …
  • God varsel der @Kusalananda. Jeg gjorde en rask løsning som i awk -F"\t" -vq="'" -vOFS="','" '$1=$1 {print "(" q $0 q "),"}' filename | sed '$s/,$/;/'. Er det noe bedre forslag?
  • Nei, at ' er en god løsning.

Svar

For å oppnå samme oppførsel som du vil med det første skriptet, kan du bruke «printf» -metoden for awk. Det gjør det mulig å kvitte seg med nye linjer som er satt av «print». Jeg tipper, manuset ditt skal skrives om slik:

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

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *