AWK - niepoprawne formatowanie polskich znaków

Bash, C, C++, Java, PHP, Ruby, GTK, Qt i wiele innych - wszystko tutaj.
Mały 1
Zakręcona Traszka
Zakręcona Traszka
Posty: 548
Rejestracja: 24 sty 2008, 15:55
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: LXDE
Architektura: x86_64

AWK - niepoprawne formatowanie polskich znaków

Post 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?
Awatar użytkownika
ethanak
Wygnańcy
Posty: 3054
Rejestracja: 04 gru 2007, 13:19
Płeć: Mężczyzna
Wersja Ubuntu: 12.04
Środowisko graficzne: GNOME
Architektura: x86
Lokalizacja: Bielsko-Biała
Kontakt:

Re: AWK - niepoprawne formatowanie polskich znaków

Post 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...
kobylecki
Piegowaty Guziec
Piegowaty Guziec
Posty: 19
Rejestracja: 05 gru 2005, 18:11
Płeć: Mężczyzna
Wersja Ubuntu: 11.10
Środowisko graficzne: Unity
Architektura: x86

Re: AWK - niepoprawne formatowanie polskich znaków

Post 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.
Mały 1
Zakręcona Traszka
Zakręcona Traszka
Posty: 548
Rejestracja: 24 sty 2008, 15:55
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: LXDE
Architektura: x86_64

Re: AWK - niepoprawne formatowanie polskich znaków

Post 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ć?
Awatar użytkownika
ethanak
Wygnańcy
Posty: 3054
Rejestracja: 04 gru 2007, 13:19
Płeć: Mężczyzna
Wersja Ubuntu: 12.04
Środowisko graficzne: GNOME
Architektura: x86
Lokalizacja: Bielsko-Biała
Kontakt:

Re: AWK - niepoprawne formatowanie polskich znaków

Post 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
Mały 1
Zakręcona Traszka
Zakręcona Traszka
Posty: 548
Rejestracja: 24 sty 2008, 15:55
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: LXDE
Architektura: x86_64

Re: AWK - niepoprawne formatowanie polskich znaków

Post 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:

Kod: Zaznacz cały

echo $[ 2,2 + 2,2 ] # wynik: 2
a awk to zrobił:

Kod: Zaznacz cały

awk 'BEGIN { print 2.2 + 2.2 }' # wynik: 2.2
:)
Awatar użytkownika
ethanak
Wygnańcy
Posty: 3054
Rejestracja: 04 gru 2007, 13:19
Płeć: Mężczyzna
Wersja Ubuntu: 12.04
Środowisko graficzne: GNOME
Architektura: x86
Lokalizacja: Bielsko-Biała
Kontakt:

Re: AWK - niepoprawne formatowanie polskich znaków

Post 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

Kod: Zaznacz cały

man 7 utf8
Mały 1
Zakręcona Traszka
Zakręcona Traszka
Posty: 548
Rejestracja: 24 sty 2008, 15:55
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: LXDE
Architektura: x86_64

Re: AWK - niepoprawne formatowanie polskich znaków

Post 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'.
Awatar użytkownika
ethanak
Wygnańcy
Posty: 3054
Rejestracja: 04 gru 2007, 13:19
Płeć: Mężczyzna
Wersja Ubuntu: 12.04
Środowisko graficzne: GNOME
Architektura: x86
Lokalizacja: Bielsko-Biała
Kontakt:

Re: AWK - niepoprawne formatowanie polskich znaków

Post autor: ethanak »

ja tak nieśmiało zasugeruję poczytanie sobie o tworzeniu własnych funkcji w awku...
Mały 1
Zakręcona Traszka
Zakręcona Traszka
Posty: 548
Rejestracja: 24 sty 2008, 15:55
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: LXDE
Architektura: x86_64

Re: AWK - niepoprawne formatowanie polskich znaków

Post autor: Mały 1 »

Dobrze, że jest nadzieja zrobienia tego przy użyciu funkcji. Oczywiście, że o nich poczytam. Dzięki.
ODPOWIEDZ

Wróć do „Programowanie”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 8 gości