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:
-
s/^/("/
zastępuje początek wiersza("
. -
s/\t/","/g
zamienia karty na","
. To jest bit, który wymaga GNUsed
. W przypadku innych implementacjised
wstaw tabulator literału zamiast\t
. -
s/$/"),/
zamienia koniec wiersza na"),
. -
$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";}"