Strona 1 z 1
AWK - niepoprawne formatowanie polskich znaków
: 13 mar 2012, 17:54
autor: Mały 1
Witam!
Podczas formatowania tekstu zauważyłem, że polecenie 'printf' napotykając polski znak źle formatuje tekst. Oto przykłady:
Kod: Zaznacz cały
awk 'BEGIN { printf "%-20s", "Data zakończenia:" > "/dev/stderr"; getline a; }'
awk 'BEGIN { printf "%-20s", "Data zakonczenia:" > "/dev/stderr"; getline b; }'
awk 'BEGIN { printf "%-20s", "Prośba:" > "/dev/stderr"; getline b; }'
awk 'BEGIN { printf "%-20s", "Prosba:" > "/dev/stderr"; getline b; }'
Wyniki:
Kod: Zaznacz cały
Data zakończenia: test
Data zakonczenia: test
Prośba: test
Prosba: test
Jak widać wyraz 'test' jest przesunięty w zależności od tego, czy przed nim formatowane pole zawiera polski znak.
To jest normalne zachowanie programu?
Czy to znaczy, że lepiej nie używać w tabelach polskich znaków?
Re: AWK - niepoprawne formatowanie polskich znaków
: 13 mar 2012, 18:07
autor: ethanak
a słyszałeś kiedy o kodowaniach wielobajtowych? awk działa na bajtach, a Ty używasz kodowania, które używa do trzech bajtów (w porywach sześciu) na znak...
Re: AWK - niepoprawne formatowanie polskich znaków
: 13 mar 2012, 18:12
autor: kobylecki
hm?
mam nadzieję, że w skrypcie nie piszesz tyle awków pod rząd; można mu przesłać program awkowy do wykonania.
Zauważ, że prosisz go o wypisanie 20 znakowych napisów, a tam gdzie masz polski znak to drukuje 19 znaków. Można zatem wysnuć wniosek, że 'ń', 'ś' i inne polskie znaki są traktowane jako dwuznak (dwa bajty są zajmowane jako reprezentacja) stąd ten błąd.
Re: AWK - niepoprawne formatowanie polskich znaków
: 13 mar 2012, 19:27
autor: Mały 1
ethanak pisze:a słyszałeś kiedy o kodowaniach wielobajtowych?
Coś tam słyszałem, ale teraz tego osobiście doświadczyłem
kobylecki pisze:mam nadzieję, że w skrypcie nie piszesz tyle awków pod rząd; można mu przesłać program awkowy do wykonania.
W skrypcie mam właśnie dużo awków tz. każda zmienna to inny awk:
Kod: Zaznacz cały
a=`awk 'BEGIN { printf "%-20s", "Data początkowa:" > "/dev/stderr"; getline a; print a }'`
b=`awk 'BEGIN { printf "%-20s", "Data końcowa:" > "/dev/stderr"; getline b; print b }'`
c=`awk 'BEGIN { printf "%-20s", "Coś innego:" > "/dev/stderr"; getline c; print c }'`
d=`awk 'BEGIN { printf "%-20s", "Jeszcze coś innego:" > "/dev/stderr"; getline d; print d }'`
Można to jeszcze uprościć?
Re: AWK - niepoprawne formatowanie polskich znaków
: 14 mar 2012, 08:31
autor: ethanak
Tu w ogóle awk nie jest potrzebny od tego zacznijmy
Kod: Zaznacz cały
echo -n "Data początkowa: ";read a
echo -n "Data końcowa: ";read b
i tak dalej
Re: AWK - niepoprawne formatowanie polskich znaków
: 14 mar 2012, 11:33
autor: Mały 1
Masz rację. Jednak moim założeniem jest zrobienie tego w awk, aby lepiej poznać ten język.
Czytać o awk zacząłem przez przypadek, kiedy to bash nie chciał zrobić prostego działania:
a awk to zrobił:
Kod: Zaznacz cały
awk 'BEGIN { print 2.2 + 2.2 }' # wynik: 2.2

Re: AWK - niepoprawne formatowanie polskich znaków
: 14 mar 2012, 12:01
autor: ethanak
No to przede wszystkim zrób to jednym skryptem a nie czterema. No i - ponieważ awk nie wie nic o wielobajtowych kodowaniach - pozostaje albo popularne wśród zaawansowanych użytkowników Worda formatowanie ręczne spacjami, albo wyliczanie szerokości napisu w znakach i dodanie iluśtam spacji na podstawie wyliczonej szerokości.
Uproszczony (zakładający poprawny UTF-8, z zakresu 16 bitów, bez połączeń znaków) algorytm polega na sprawdzeniu wartości pierwszego bajtu znaku. Jeśli wartość < 128, jest to pojedynczy bajt. Jeśli (wartość & 0xe0) == 0xc0, znak jest dwubajtowy. Jeśli nie, radośnie zakładasz że nikt hieroglifami egipskimi nie pisał i znak ma trzy bajty.
Mam nadzieję że jakoś przystępnie się wyraziłem... w razie jakbyś chciał problem zgłębiać to
Re: AWK - niepoprawne formatowanie polskich znaków
: 14 mar 2012, 20:00
autor: Mały 1
Dziękuje za wszystkie wyjaśnienia, na pewno się przydadzą.
Postaram się to wszystko zrobić w jednym skrypcie tz. w jednym bloku awk 'BEGIN {…}'.
Chciałbym też nie nadużywać polecenia 'print'. Dlatego zamiast tak:
Kod: Zaznacz cały
awk 'BEGIN { printf "%-30s", "Liczba dni:"; print int((("'"$d"'" - "'"$c"'") + 43200) / 86400) }'
Zrobiłem tak:
Kod: Zaznacz cały
awk 'BEGIN { printf "%-30s %-s\n", "Liczba dni:", int((("'"$d"'" - "'"$c"'") + 43200) / 86400) }'
Teraz nie wiem, czy to w ogóle będzie możliwe, aby zrobić podobnie w tym przykładzie:
Kod: Zaznacz cały
awk 'BEGIN { printf "%-30s", "Data założenia:" > "/dev/stderr"; getline a; print a }'
Czy można tylko przy użyciu polecenia 'printf' pobrać do getline, a następnie wydrukować 'a'?
Chodzi o to, aby się pozbyć polecenia 'print'.
Re: AWK - niepoprawne formatowanie polskich znaków
: 14 mar 2012, 20:23
autor: ethanak
ja tak nieśmiało zasugeruję poczytanie sobie o tworzeniu własnych funkcji w awku...
Re: AWK - niepoprawne formatowanie polskich znaków
: 14 mar 2012, 20:41
autor: Mały 1
Dobrze, że jest nadzieja zrobienia tego przy użyciu funkcji. Oczywiście, że o nich poczytam. Dzięki.