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:
-
s/^/("/
erstatter start på linje med("
. -
s/\t/","/g
erstatter faner med","
. Dette er biten som krever GNUsed
. For andresed
implementeringer, sett inn en bokstavelig fane i stedet for\t
. -
s/$/"),/
erstatter slutten av linjen med"),
. -
$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";}"