Jak zoptymalizować skrypt za pomocą NF i pętli for

Mam kilka plików, każdy z inną liczbą kolumn. Chcę je przekonwertować, aby wstawić je do bazy danych

Na przykład plik 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 

Moje pożądane wyjście to:

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

Aby to osiągnąć, używam następującego skryptu:

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

I działa dobrze, Problem polega na tym, że znajduję inny plik z inną liczbą kolumn, więc muszę ręcznie zmodyfikować skrypt.

Wiem, że mogę uzyskać liczbę kolumn ze zmienną NF AWK, ale jak połączyć tę zmienną z pętlą for w skrypcie?

Kiedy próbuję

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

Otrzymuję taki wynik:

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

Komentarze

  • Czy w oryginalnym pliku jest separator tabulatora, czy tylko " trochę białych znaków "?
  • To jest separator tabulatorów

Odpowiedź

Używając 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"); 

Plik składa się z czterech części:

  1. s/^/("/ zastępuje początek wiersza (".
  2. s/\t/","/g zamienia karty na ",". To jest bit, który wymaga GNU sed. W przypadku innych implementacji sed wstaw tabulator literału zamiast \t.
  3. s/$/"),/ zamienia koniec wiersza na "),.
  4. $s/.$/;/ zastępuje przecinek na końcu ostatnia linia (tylko) z ;.

Komentarze

  • Uruchamiam skrypt i podpowiada " > " jako oczekiwanie na coś
  • @ user3333911 Mam niezgodne cytaty z wcześniejszej wersji. Naprawiono i przetestowano.

Odpowiedź

Jeśli plik wejściowy jest rozdzielany tabulatorami, możesz spróbować następujących rozwiązań:

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

Lub umieść cudzysłowy w funkcji drukowania:

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

Komentarze

  • Uważaj na przecinki na końcu wszystkich linii z wyjątkiem ostatniego …
  • Dobra uwaga @Kusalananda. Zrobiłem szybką poprawkę, jak w awk -F"\t" -vq="'" -vOFS="','" '$1=$1 {print "(" q $0 q "),"}' filename | sed '$s/,$/;/'. Czy jest jakaś lepsza sugestia?
  • Nie, to ' to dobre rozwiązanie.

Odpowiedź

Aby osiągnąć takie samo zachowanie, jak chcesz ze swoim początkowym skryptem, możesz użyć metody „printf” awk. Pozwala pozbyć się znaków nowej linii wstawianych przez „print”. Domyślam się, że Twój skrypt powinien zostać przepisany w następujący sposób:

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

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *