Ievads
Viss sÄkÄs ar Ä«su skriptu, kuram vajadzÄja apvienot adreses informÄciju e-pasts darbinieki, kas iegÅ«ti no adresÄtu saraksta lietotÄju saraksta, ar darbinieku amatiem, kas iegÅ«ti no HR departamenta datu bÄzes. Abi saraksti tika eksportÄti uz Unicode teksta failiem UTF-8 un saglabÄts ar Unix rindu galotnÄm.
Saturs mail.txt
ŠŠ²Š°Š½Š¾Š² ŠŠ½Š“ŃŠµŠ¹;[email protected]
Saturs buhg.txt
ŠŠ²Š°Š½Š¾Š²Š° ŠŠ»Š»Š°;Š¼Š°Š»ŃŃ
ŠŠ»ŠŗŠøŠ½Š° ŠŠ»Š»Š°;ŠŗŃŠ°Š½Š¾Š²ŃŠøŃŠ°
ŠŠ²Š°Š½Š¾Š² ŠŠ½Š“ŃŠµŠ¹;ŃŠ»ŠµŃŠ°ŃŃ
ŠŠ±Š°ŠŗŠ°Š½Š¾Š² ŠŠøŃ
Š°ŠøŠ»;Š¼Š°Š»ŃŃ
Lai apvienotu, faili tika sakÄrtoti ar Unix komandu Ŕķirot un iesniegts Unix programmas ievadei pievienoties, kas negaidÄ«ti neizdevÄs ar kļūdu:
$> sort buhg.txt > buhg.srt
$> sort mail.txt > mail.srt
$> join buhg.srt mail.srt > result
join: buhg.srt:4: is not sorted: ŠŠ²Š°Š½Š¾Š² ŠŠ½Š“ŃŠµŠ¹;ŃŠ»ŠµŃŠ°ŃŃ
Apskatot ŔķiroÅ”anas rezultÄtu ar acÄ«m, bija redzams, ka kopumÄ Å”Ä·iroÅ”ana ir pareiza, bet vÄ«rieÅ”u un sievieÅ”u uzvÄrdu sakritÄ«bas gadÄ«jumÄ sievieÅ”u uzvÄrdi ir pirms vÄ«rieÅ”u uzvÄrdu:
$> sort buhg.txt
ŠŠ±Š°ŠŗŠ°Š½Š¾Š² ŠŠøŃ
Š°ŠøŠ»;Š¼Š°Š»ŃŃ
ŠŠ»ŠŗŠøŠ½Š° ŠŠ»Š»Š°;ŠŗŃŠ°Š½Š¾Š²ŃŠøŃŠ°
ŠŠ²Š°Š½Š¾Š²Š° ŠŠ»Š»Š°;Š¼Š°Š»ŃŃ
ŠŠ²Š°Š½Š¾Š² ŠŠ½Š“ŃŠµŠ¹;ŃŠ»ŠµŃŠ°ŃŃ
IzskatÄs pÄc ŔķiroÅ”anas kļūmes Unicode vai pÄc feminisma izpausmes ŔķiroÅ”anas algoritmÄ. Pirmais, protams, ir ticamÄks.
PagaidÄm atliksim pievienoties un koncentrÄties uz Ŕķirot. MÄÄ£inÄsim atrisinÄt problÄmu, izmantojot zinÄtnisku poking. Vispirms mainÄ«sim lokalizÄciju no lv par ru_ru. Lai sakÄrtotu, bÅ«tu pietiekami iestatÄ«t vides mainÄ«go LC_COLATE, bet mÄs netÄrÄsim laiku sÄ«kumiem:
$> LANG=ru_RU.UTF-8 sort buhg.txt
ŠŠ±Š°ŠŗŠ°Š½Š¾Š² ŠŠøŃ
Š°ŠøŠ»;Š¼Š°Š»ŃŃ
ŠŠ»ŠŗŠøŠ½Š° ŠŠ»Š»Š°;ŠŗŃŠ°Š½Š¾Š²ŃŠøŃŠ°
ŠŠ²Š°Š½Š¾Š²Š° ŠŠ»Š»Š°;Š¼Š°Š»ŃŃ
ŠŠ²Š°Š½Š¾Š² ŠŠ½Š“ŃŠµŠ¹;ŃŠ»ŠµŃŠ°ŃŃ
Nekas nemainÄ«jÄs.
MÄÄ£inÄsim pÄrkodÄt failus viena baita kodÄjumÄ:
$> iconv -f UTF-8 -t KOI8-R buhg.txt
| LANG=ru_RU.KOI8-R sort
| iconv -f KOI8-R -t UTF8
Atkal nekas nav mainījies.
Neko nevar darÄ«t, bÅ«s jÄmeklÄ risinÄjums internetÄ. Par krievu uzvÄrdiem tieÅ”i nekas nav, bet ir jautÄjumi par citÄm ŔķiroÅ”anas dÄ«vainÄ«bÄm. PiemÄram, Å”eit ir problÄma:
Atbilde ir standarta visur: izmantojiet programmÄtÄja lokalizÄciju "C" un tu bÅ«si laimÄ«gs. PamÄÄ£inÄsim:
$> LANG=C sort buhg.txt
ŠŠ»ŠŗŠøŠ½Š° ŠŠ»Š»Š°;ŠŗŃŠ°Š½Š¾Š²ŃŠøŃŠ°
ŠŠ±Š°ŠŗŠ°Š½Š¾Š² ŠŠøŃ
Š°ŠøŠ»;Š¼Š°Š»ŃŃ
ŠŠ²Š°Š½Š¾Š² ŠŠ½Š“ŃŠµŠ¹;ŃŠ»ŠµŃŠ°ŃŃ
ŠŠ²Š°Š½Š¾Š²Š° ŠŠ»Š»Š°;Š°Š“Š²Š¾ŠŗŠ°Ń
Kaut kas ir mainÄ«jies. Ivanovi ierindojÄs pareizÄ secÄ«bÄ, lai gan Jolkina kaut kur paslÄ«dÄja. AtgriezÄ«simies pie sÄkotnÄjÄs problÄmas:
$> LANG=C sort buhg.txt > buhg.srt
$> LANG=C sort mail.txt > mail.srt
$> LANG=C join buhg.srt mail.srt > result
Tas strÄdÄja bez kļūdÄm, kÄ solÄ«ja internets. Un tas neskatoties uz Yolkina pirmajÄ rindÄ.
Å Ä·iet, ka problÄma ir atrisinÄta, bet katram gadÄ«jumam izmÄÄ£inÄsim citu krievu kodÄjumu - Windows CP1251:
$> iconv -f UTF-8 -t CP1251 buhg.txt
| LANG=ru_RU.CP1251 sort
| iconv -f CP1251 -t UTF8
Å Ä·iroÅ”anas rezultÄts, dÄ«vainÄ kÄrtÄ, sakritÄ«s ar lokalizÄciju "C", un attiecÄ«gi viss piemÄrs darbojas bez kļūdÄm. Kaut kÄda mistika.
ProgrammÄÅ”anÄ man nepatÄ«k mistika, jo tÄ parasti maskÄ kļūdas. Mums bÅ«s nopietni jÄizpÄta, kÄ tas darbojas. Ŕķirot un ko tas ietekmÄ? LC_COLATE .
BeigÄs mÄÄ£inÄÅ”u atbildÄt uz jautÄjumiem:
- kÄpÄc sievieÅ”u uzvÄrdi tika sakÄrtoti nepareizi?
- kÄpÄc LANG=ru_RU.CP1251 izrÄdÄ«jÄs lÄ«dzvÄrtÄ«gs LANG=C
- kÄpÄc Ŕķirot Šø pievienoties dažÄdas idejas par sakÄrtoto virkÅu secÄ«bu
- kÄpÄc visos manos piemÄros ir kļūdas?
- beidzot, kÄ sakÄrtot virknes pÄc saviem ieskatiem
KÄrtoÅ”ana Unicode
PirmÄ pietura bÅ«s tehniskais ziÅojums Nr.10 ar nosaukumu
SalÄ«dzinÄÅ”ana ā virkÅu āsalÄ«dzinÄÅ”anaā ir jebkura ŔķiroÅ”anas algoritma pamatÄ. Algoritmi paÅ”i var atŔķirties ("burbulis", "apvienot", "Ätri"), taÄu tie visi izmantos virkÅu pÄra salÄ«dzinÄjumu, lai noteiktu secÄ«bu, kÄdÄ tie parÄdÄs.
VirkÅu kÄrtoÅ”ana dabiskajÄ valodÄ ir diezgan sarežģīta problÄma. Pat visvienkÄrÅ”Äkajos viena baita kodÄjumos burtu secÄ«ba alfabÄtÄ, pat kaut kÄdÄ veidÄ atŔķiras no angļu latÄ«Åu alfabÄta, vairs nesakritÄ«s ar ciparu vÄrtÄ«bu secÄ«bu, ar kÄdu Å”ie burti ir kodÄti. TÄtad vÄcu alfabÄtÄ burts Ć stÄv starp Š Šø P, un kodÄjumÄ CP850 viÅa nonÄk starp Ćæ Šø Ć.
Varat mÄÄ£inÄt abstrahÄties no konkrÄta kodÄjuma un apsvÄrt āideÄlosā burtus, kas ir sakÄrtoti noteiktÄ secÄ«bÄ, kÄ tas tiek darÄ«ts Unicode. KodÄjumi UTF8, UTF16 vai viens baits KOI8-R (ja ir nepiecieÅ”ama ierobežota Unikoda apakÅ”kopa) sniegs atŔķirÄ«gus burtu ciparu attÄlojumus, bet atsauksies uz tiem paÅ”iem pamata tabulas elementiem.
IzrÄdÄs, pat ja mÄs izveidosim simbolu tabulu no nulles, mÄs nevarÄsim tai pieŔķirt universÄlu simbolu secÄ«bu. DažÄdos nacionÄlajos alfabÄtos, kuros tiek izmantoti vieni un tie paÅ”i burti, Å”o burtu secÄ«ba var atŔķirties. PiemÄram, franÄu valodÄ Ć tiks uzskatÄ«ts par ligatÅ«ru un sakÄrtots kÄ virkne AE. NorvÄÄ£u valodÄ Ć bÅ«s atseviŔķa vÄstule, kas atrodas pÄc Z. Starp citu, papildus ligatÅ«rÄm patÄ«k Ć Ir burti, kas rakstÄ«ti ar vairÄkiem simboliem. TÄtad Äehu alfabÄtÄ ir burts Ch, kas stÄv starp H Šø I.
Papildus alfabÄta atŔķirÄ«bÄm ir arÄ« citas nacionÄlÄs tradÄ«cijas, kas ietekmÄ Å”Ä·iroÅ”anu. Jo Ä«paÅ”i rodas jautÄjums: kÄdÄ secÄ«bÄ vÄrdnÄ«cÄ jÄparÄdÄs vÄrdiem, kas sastÄv no lielajiem un mazajiem burtiem? Å Ä·iroÅ”anu var ietekmÄt arÄ« pieturzÄ«mju lietoÅ”ana. SpÄÅu valodÄ jautÄjoÅ”a teikuma sÄkumÄ tiek lietota apgriezta jautÄjuma zÄ«me (Vai tev patÄ«k mÅ«zika?). Å ajÄ gadÄ«jumÄ ir skaidrs, ka jautÄjoÅ”os teikumus nevajadzÄtu grupÄt atseviÅ”Ä·Ä klasterÄ« Ärpus alfabÄta, bet kÄ sakÄrtot rindas ar citÄm pieturzÄ«mÄm?
Es nekavÄÅ”os pie virkÅu ŔķiroÅ”anas valodÄs, kas ļoti atŔķiras no Eiropas valodÄm. Å
emiet vÄrÄ, ka valodÄs ar rakstÄ«Å”anas virzienu no labÄs uz kreiso vai no augÅ”as uz leju, rakstzÄ«mes rindÄs, visticamÄk, tiek saglabÄtas lasÄ«Å”anas secÄ«bÄ, un pat rakstÄ«Å”anas sistÄmÄm, kas nav alfabÄta, ir savi veidi, kÄ sakÄrtot rindas pÄc rakstzÄ«mes. . PiemÄram, hieroglifus var sakÄrtot pÄc stila (
Pamatojoties uz iepriekÅ” uzskaitÄ«tajÄm funkcijÄm, tika formulÄtas pamatprasÄ«bas virkÅu salÄ«dzinÄÅ”anai, pamatojoties uz Unikoda tabulÄm:
- virkÅu salÄ«dzinÄÅ”ana nav atkarÄ«ga no rakstzÄ«mju atraÅ”anÄs vietas kodu tabulÄ;
- rakstzÄ«mju secÄ«bas, kas veido vienu rakstzÄ«mi, tiek reducÄtas lÄ«dz kanoniskajai formai (A + augÅ”Äjais aplis ir tÄds pats kÄ Ć );
- SalÄ«dzinot virknes, rakstzÄ«me tiek aplÅ«kota virknes kontekstÄ un, ja nepiecieÅ”ams, tiek apvienota ar tÄs kaimiÅiem vienÄ salÄ«dzinÄÅ”anas vienÄ«bÄ (Ch Äehu valodÄ) vai ir sadalÄ«ts vairÄkos (Ć franciski);
- visas nacionÄlÄs pazÄ«mes (alfabÄts, lielie/mazie burti, pieturzÄ«mes, rakstÄ«Å”anas veidu secÄ«ba) jÄkonfigurÄ lÄ«dz manuÄlai secÄ«bas (emoji) pieŔķirÅ”anai;
- salÄ«dzinÄÅ”ana ir svarÄ«ga ne tikai kÄrtoÅ”anai, bet arÄ« daudzÄs citÄs vietÄs, piemÄram, rindu diapazonu norÄdÄ«Å”anai (aizstÄt {A... z} stipri iesist);
- salÄ«dzinÄÅ”ana jÄveic diezgan Ätri.
TurklÄt ziÅojuma autori formulÄja salÄ«dzinÄÅ”anas Ä«paŔības, uz kurÄm algoritmu izstrÄdÄtÄjiem nevajadzÄtu paļauties:
- salÄ«dzinÄÅ”anas algoritmam nevajadzÄtu prasÄ«t atseviŔķu rakstzÄ«mju kopu katrai valodai (krievu un ukraiÅu valodÄs ir lielÄka daļa kirilicas rakstzÄ«mju);
- salÄ«dzinÄjumam nevajadzÄtu balstÄ«ties uz rakstzÄ«mju secÄ«bu Unikoda tabulÄs;
- virknes svars nedrÄ«kst bÅ«t virknes atribÅ«ts, jo vienai un tai paÅ”ai virknei dažÄdos kultÅ«ras kontekstos var bÅ«t atŔķirÄ«gs svars;
- rindu svars var mainÄ«ties, apvienojot vai sadalot (no x < y no tÄ neizriet xz < yz);
- dažÄdas virknes ar vienÄdu svaru tiek uzskatÄ«tas par vienÄdÄm no ŔķiroÅ”anas algoritma viedokļa. Å Ädu virkÅu papildu secÄ«bas ievieÅ”ana ir iespÄjama, taÄu tas var pasliktinÄt veiktspÄju;
- AtkÄrtotas ŔķiroÅ”anas laikÄ rindas ar vienÄdu svaru var tikt apmainÄ«tas. Robustums ir noteikta kÄrtoÅ”anas algoritma Ä«paŔība, nevis virkÅu salÄ«dzinÄÅ”anas algoritma Ä«paŔība (skatiet iepriekÅ”Äjo rindkopu);
- Å Ä·iroÅ”anas noteikumi laika gaitÄ var mainÄ«ties, kultÅ«ras tradÄ«cijÄm pilnveidojoties/mainoties.
TÄpat ir noteikts, ka salÄ«dzinÄÅ”anas algoritms neko nezina par apstrÄdÄjamo virkÅu semantiku. TÄdÄjÄdi virknes, kas sastÄv tikai no cipariem, nevajadzÄtu salÄ«dzinÄt kÄ skaitļus, un angļu valodas nosaukumu sarakstos raksts (Beatles, The).
Lai izpildÄ«tu visas noteiktÄs prasÄ«bas, tiek piedÄvÄts daudzlÄ«meÅu (faktiski Äetru lÄ«meÅu) tabulu ŔķiroÅ”anas algoritms.
IepriekÅ” rakstzÄ«mes virknÄ tika reducÄtas lÄ«dz kanoniskajai formai un sagrupÄtas salÄ«dzinÄÅ”anas vienÄ«bÄs. Katrai salÄ«dzinÄÅ”anas vienÄ«bai tiek pieŔķirti vairÄki svari, kas atbilst vairÄkiem salÄ«dzinÄÅ”anas lÄ«meÅiem. SalÄ«dzinÄÅ”anas vienÄ«bu svari ir sakÄrtotu kopu elementi (Å”ajÄ gadÄ«jumÄ veseli skaitļi), kurus var salÄ«dzinÄt vairÄk vai mazÄk. ÄŖpaÅ”a nozÄ«me IgnorÄts (0x0) nozÄ«mÄ, ka attiecÄ«gajÄ salÄ«dzinÄÅ”anas lÄ«menÄ« Ŕī vienÄ«ba nav iesaistÄ«ta salÄ«dzinÄÅ”anÄ. StÄ«gu salÄ«dzinÄÅ”anu var atkÄrtot vairÄkas reizes, izmantojot atbilstoÅ”o lÄ«meÅu svarus. KatrÄ lÄ«menÄ« divu rindu salÄ«dzinÄÅ”anas vienÄ«bu svari tiek secÄ«gi salÄ«dzinÄti savÄ starpÄ.
DažÄdos nacionÄlo tradÄ«ciju algoritma variantos koeficientu vÄrtÄ«bas var atŔķirties, taÄu Unikoda standartÄ ir iekļauta pamata svaru tabula - "NoklusÄjuma Unikoda ŔķiroÅ”anas elementu tabula" (DUCET). Es vÄlos atzÄ«mÄt, ka mainÄ«gÄ iestatÄ«Å”ana LC_COLATE patiesÄ«bÄ ir norÄde uz svara tabulas atlasi virkÅu salÄ«dzinÄÅ”anas funkcijÄ.
SvÄruma koeficienti DUCET sakÄrtots Å”Ädi:
- pirmajÄ lÄ«menÄ« visi burti tiek reducÄti lÄ«dz vienam un tam paÅ”am reÄ£istram, diakritiskÄs zÄ«mes tiek atmestas, pieturzÄ«mes (ne visas) tiek ignorÄtas;
- otrajÄ lÄ«menÄ« tiek Åemtas vÄrÄ tikai diakritiskÄs zÄ«mes;
- treÅ”ajÄ lÄ«menÄ« tiek Åemts vÄrÄ tikai gadÄ«jums;
- ceturtajÄ lÄ«menÄ« tiek Åemtas vÄrÄ tikai pieturzÄ«mes.
SalÄ«dzinÄÅ”ana notiek vairÄkos piegÄjienos: vispirms tiek salÄ«dzinÄti pirmÄ lÄ«meÅa koeficienti; ja svari sakrÄ«t, tad tiek veikta atkÄrtota salÄ«dzinÄÅ”ana ar otrÄ lÄ«meÅa svariem; tad varbÅ«t treÅ”Ä un ceturtÄ.
SalÄ«dzinÄjums beidzas, kad rindÄs ir atbilstoÅ”as āāsalÄ«dzinÄÅ”anas vienÄ«bas ar dažÄdu svaru. Rindas, kurÄm ir vienÄds svars visos Äetros lÄ«meÅos, tiek uzskatÄ«tas par vienÄdÄm.
Å is algoritms (ar virkni papildu tehnisko detaļu) deva nosaukumu ziÅojumam Nr. 10 - "Unikoda kÄrtoÅ”anas algoritms" (ACU).
Å eit mÅ«su piemÄrÄ redzamÄ Å”Ä·iroÅ”anas uzvedÄ«ba kļūst nedaudz skaidrÄka. BÅ«tu jauki to salÄ«dzinÄt ar Unicode standartu.
Lai pÄrbaudÄ«tu implementÄcijas ACU ir Ä«paÅ”s
ManuÄli pÄrbaudot, vai rindas ir sakÄrtotas pareizi atbilstoÅ”i DUCET tas bÅ«tu diezgan nogurdinoÅ”i, bet, par laimi mums, ir priekÅ”zÄ«mÄ«ga bibliotÄkas ievieÅ”ana darbam ar Unicode - "
Å Ä«s bibliotÄkas tÄ«mekļa vietnÄ, kas izstrÄdÄta gadÄ IBM, ir demonstrÄcijas lapas, tostarp
ŠŠ±Š°ŠŗŠ°Š½Š¾Š² ŠŠøŃ
Š°ŠøŠ»;Š¼Š°Š»ŃŃ
ŠŠ»ŠŗŠøŠ½Š° ŠŠ»Š»Š°;ŠŗŃŠ°Š½Š¾Š²ŃŠøŃŠ°
ŠŠ²Š°Š½Š¾Š² ŠŠ½Š“ŃŠµŠ¹;ŃŠ»ŠµŃŠ°ŃŃ
ŠŠ²Š°Š½Š¾Š²Š° ŠŠ»Š»Š°;Š°Š“Š²Š¾ŠŗŠ°Ń
Starp citu, vietne ICU SalÄ«dzinÄÅ”anas algoritma skaidrojumu var atrast, apstrÄdÄjot pieturzÄ«mes. PiemÄros
Unicode mums palÄ«dzÄja, bet meklÄjiet dÄ«vainas uzvedÄ«bas iemeslus Ŕķirot Š² Linux bÅ«s jÄiet kaut kur citur.
KÄrtoÅ”ana programmÄ glibc
Ätrs utilÄ«tu pirmkodu skats Ŕķirot no GNU Core Utils parÄdÄ«ja, ka paÅ”Ä utilÄ«tprogrammÄ lokalizÄcija ir atkarÄ«ga no mainÄ«gÄ paÅ”reizÄjÄs vÄrtÄ«bas drukÄÅ”anas LC_COLATE kad darbojas atkļūdoÅ”anas režīmÄ:
$ sort --debug buhg.txt > buhg.srt
sort: using āen_US.UTF8ā sorting rules
VirkÅu salÄ«dzinÄÅ”ana tiek veikta, izmantojot standarta funkciju strcoll, kas nozÄ«mÄ, ka viss interesantais ir bibliotÄkÄ glibc.
uz Wiki projekts glibc veltÄ«ta stÄ«gu salÄ«dzinÄÅ”anai
InteresantÄkÄ informÄcija par Wiki bija saite uz
Tagad, kad mums ir visa informÄcija par algoritmu un palÄ«gtabulÄm, mÄs varam atgriezties pie sÄkotnÄjÄs problÄmas un saprast, kÄ pareizi kÄrtot virknes krievu lokalizÄcijÄ.
ISO 14651 / 14652
MÅ«s interesÄjoÅ”Äs tabulas pirmkods CTT lielÄkajÄ daÄ¼Ä izplatÄ«Å”anu Linux ir katalogÄ /usr/share/i18n/locales/. Pati tabula ir failÄ iso14651_t1_common. Tad Ŕī ir faila direktÄ«va kopÄt iso14651_t1_common iekļauts failÄ iso14651_t1, kas savukÄrt ir iekļauts nacionÄlajos failos, t.sk lv Šø ru_ru. LielÄkajÄ daÄ¼Ä izplatÄ«Å”anu Linux Visi avota faili ir iekļauti pamata instalÄcijÄ, taÄu, ja to nav, jums bÅ«s jÄinstalÄ papildu pakotne no izplatÄ«Å”anas.
Faila struktÅ«ra iso14651_t1 var Ŕķist Å”ausmÄ«gi runÄ«gs, ar nepÄrprotamiem vÄrdu konstruÄÅ”anas noteikumiem, bet, ja paskatÄs, tad viss ir pavisam vienkÄrÅ”i. StruktÅ«ra ir aprakstÄ«ta standartÄ ISO 14652, kuras kopiju var lejupielÄdÄt no vietnes
Faila struktÅ«ra izskatÄs Å”Ädi:
PÄc noklusÄjuma rakstzÄ«me tiek izmantota kÄ atsoļa rakstzÄ«me, un rindas beigas pÄc rakstzÄ«mes # ir komentÄrs. Abus simbolus var definÄt no jauna, kas tiek darÄ«ts jaunajÄ tabulas versijÄ:
escape_char /
comment_char %
FailÄ bÅ«s marÄ·ieri Å”ÄdÄ formÄtÄ vai (kur x - heksadecimÄlais cipars). Å is ir Unikoda koda punktu heksadecimÄlais attÄlojums kodÄjumÄ UCS-4 (UTF-32). Visi pÄrÄjie elementi leÅÄ·a iekavÄs (ieskaitot , un tamlÄ«dzÄ«gi) tiek uzskatÄ«tas par vienkÄrÅ”Äm virkÅu konstantÄm, kurÄm Ärpus konteksta ir maza nozÄ«me.
String LC_COLATE norÄda, ka pÄc tam sÄkas dati, kas apraksta virkÅu salÄ«dzinÄÅ”anu.
PirmkÄrt, salÄ«dzinÄÅ”anas tabulÄ ir norÄdÄ«ti nosaukumi svariem un nosaukumi simbolu kombinÄcijÄm. VispÄrÄ«gi runÄjot, abu veidu nosaukumi pieder divÄm dažÄdÄm entÄ«tijÄm, taÄu faktiskajÄ failÄ tie ir sajaukti. Svaru nosaukumus norÄda atslÄgvÄrds salÄ«dzinÄÅ”anas simbols (salÄ«dzinÄjuma rakstzÄ«me), jo, salÄ«dzinot, Unikoda rakstzÄ«mes, kurÄm ir vienÄds svars, tiks uzskatÄ«tas par lÄ«dzvÄrtÄ«gÄm rakstzÄ«mÄm.
KopÄjais sadaļas garums paÅ”reizÄjÄ faila redakcijÄ ir aptuveni 900 rindiÅas. Es izvilku piemÄrus no vairÄkÄm vietÄm, lai parÄdÄ«tu nosaukumu patvaļību un vairÄkus sintakses veidus.
LC_COLLATE
collating-symbol <RES-1>
collating-symbol <BLK>
collating-symbol <MIN>
collating-symbol <WIDE>
...
collating-symbol <ARABIC>
collating-symbol <ETHPC>
collating-symbol <OSMANYA>
...
collating-symbol <S1D000>..<S1D35F>
collating-symbol <SFFFF> % Guaranteed largest symbol value. Keep at end of this list
...
collating-element <U0413_0301> from "<U0413><U0301>"
collating-element <U0413_0341> from "<U0413><U0341>"
- salÄ«dzinÄÅ”anas simbols reÄ£istrÄ virkni OSMANYA svaru nosaukumu tabulÄ
- salÄ«dzinÄÅ”anas simbols .. reÄ£istrÄ nosaukumu secÄ«bu, kas sastÄv no prefiksa S un heksadecimÄlais ciparu sufikss no 1D000 lÄ«dz 1D35F.
- FFFF Š² salÄ«dzinÄÅ”anas simbols izskatÄs kÄ liels neparakstÄ«ts vesels skaitlis heksadecimÄlÄ, bet tas ir tikai nosaukums, kas varÄtu izskatÄ«ties
- nosaukums nozÄ«mÄ koda punktu kodÄÅ”anÄ UCS-4
- salÄ«dzinÄÅ”anas elements no "" reÄ£istrÄ jaunu nosaukumu Unikoda punktu pÄrim.
Kad svaru nosaukumi ir definÄti, tiek norÄdÄ«ti faktiskie svari. TÄ kÄ salÄ«dzinÄjumÄ ir svarÄ«gas tikai relÄcijas ālielÄks par mazÄkā, svÄrumus nosaka vienkÄrÅ”a saraksta nosaukumu secÄ«ba. Vispirms tiek uzskaitÄ«ti āvieglÄkieā svari, pÄc tam āsmagÄkieā. AtgÄdinÄÅ”u, ka katrai Unikoda rakstzÄ«mei ir pieŔķirti Äetri dažÄdi svari. Å eit tie ir apvienoti vienÄ sakÄrtotÄ secÄ«bÄ. TeorÄtiski jebkuru simbolisku nosaukumu varÄtu izmantot jebkurÄ no Äetriem lÄ«meÅiem, taÄu komentÄri liecina, ka izstrÄdÄtÄji garÄ«gi sadala nosaukumus lÄ«meÅos.
% Symbolic weight assignments
% Third-level weight assignments
<RES-1>
<BLK>
<MIN>
<WIDE>
...
% Second-level weight assignments
<BASE>
<LOWLINE> % COMBINING LOW LINE
<PSILI> % COMBINING COMMA ABOVE
<DASIA> % COMBINING REVERSED COMMA ABOVE
...
% First-level weight assignments
<S0009> % HORIZONTAL TABULATION
<S000A> % LINE FEED
<S000B> % VERTICAL TABULATION
...
<S0434> % CYRILLIC SMALL LETTER DE
<S0501> % CYRILLIC SMALL LETTER KOMI DE
<S0452> % CYRILLIC SMALL LETTER DJE
<S0503> % CYRILLIC SMALL LETTER KOMI DJE
<S0453> % CYRILLIC SMALL LETTER GJE
<S0499> % CYRILLIC SMALL LETTER ZE WITH DESCENDER
<S0435> % CYRILLIC SMALL LETTER IE
<S04D7> % CYRILLIC SMALL LETTER IE WITH BREVE
<S0454> % CYRILLIC SMALL LETTER UKRAINIAN IE
<S0436> % CYRILLIC SMALL LETTER ZHE
Visbeidzot, faktiskÄ svara tabula.
Svaru sadaļa ir ietverta atslÄgvÄrdu rindÄs order_start Šø order_end. Papildu iespÄjas order_start noteikt, kÄdÄ virzienÄ tiek skenÄtas rindas katrÄ salÄ«dzinÄÅ”anas lÄ«menÄ«. NoklusÄjuma iestatÄ«jums ir uz priekÅ”u. Sadaļas pamattekstu veido rindas, kurÄs ir simbola kods un tÄ Äetri svari. RakstzÄ«mju kodu var attÄlot ar paÅ”u rakstzÄ«mi, koda punktu vai iepriekÅ” definÄtu simbolisku nosaukumu. Svarus var pieŔķirt arÄ« simboliskiem nosaukumiem, koda punktiem vai paÅ”iem simboliem. Ja tiek izmantoti koda punkti vai rakstzÄ«mes, to svars ir tÄds pats kÄ koda punkta skaitliskÄ vÄrtÄ«ba (pozÄ«cija Unikoda tabulÄ). RakstzÄ«mes, kas nav skaidri norÄdÄ«tas (kÄ es saprotu), tiek uzskatÄ«tas par pieŔķirtÄm tabulai ar primÄro svaru, kas atbilst pozÄ«cijai Unicode tabulÄ. ÄŖpaÅ”a svara vÄrtÄ«ba IgnorÄt nozÄ«mÄ, ka simbols tiek ignorÄts atbilstoÅ”Ä salÄ«dzinÄÅ”anas lÄ«menÄ«.
Lai parÄdÄ«tu svaru struktÅ«ru, es izvÄlÄjos trÄ«s diezgan acÄ«mredzamus fragmentus:
- rakstzÄ«mes, kuras tiek pilnÄ«bÄ ignorÄtas
- simboli, kas lÄ«dzvÄrtÄ«gi skaitlim trÄ«s pirmajos divos lÄ«meÅos
- kirilicas alfabÄta sÄkums, kurÄ nav diakritiskÄs zÄ«mes, un tÄpÄc tas ir sakÄrtots galvenokÄrt pÄc pirmÄ un treÅ”Ä lÄ«meÅa.
order_start forward;forward;forward;forward,position
<U0000> IGNORE;IGNORE;IGNORE;IGNORE % NULL (in 6429)
<U0001> IGNORE;IGNORE;IGNORE;IGNORE % START OF HEADING (in 6429)
<U0002> IGNORE;IGNORE;IGNORE;IGNORE % START OF TEXT (in 6429)
...
<U0033> <S0033>;<BASE>;<MIN>;<U0033> % DIGIT THREE
<UFF13> <S0033>;<BASE>;<WIDE>;<UFF13> % FULLWIDTH DIGIT THREE
<U2476> <S0033>;<BASE>;<COMPAT>;<U2476> % PARENTHESIZED DIGIT THREE
<U248A> <S0033>;<BASE>;<COMPAT>;<U248A> % DIGIT THREE FULL STOP
<U1D7D1> <S0033>;<BASE>;<FONT>;<U1D7D1> % MATHEMATICAL BOLD DIGIT THREE
...
<U0430> <S0430>;<BASE>;<MIN>;<U0430> % CYRILLIC SMALL LETTER A
<U0410> <S0430>;<BASE>;<CAP>;<U0410> % CYRILLIC CAPITAL LETTER A
<U04D1> <S04D1>;<BASE>;<MIN>;<U04D1> % CYRILLIC SMALL LETTER A WITH BREVE
<U0430_0306> <S04D1>;<BASE>;<MIN>;<U04D1> % CYRILLIC SMALL LETTER A WITH BREVE
...
<U0431> <S0431>;<BASE>;<MIN>;<U0431> % CYRILLIC SMALL LETTER BE
<U0411> <S0431>;<BASE>;<CAP>;<U0411> % CYRILLIC CAPITAL LETTER BE
<U0432> <S0432>;<BASE>;<MIN>;<U0432> % CYRILLIC SMALL LETTER VE
<U0412> <S0432>;<BASE>;<CAP>;<U0412> % CYRILLIC CAPITAL LETTER VE
...
order_end
Tagad varat atgriezties pie piemÄru kÄrtoÅ”anas no raksta sÄkuma. Slazds atrodas Å”ajÄ svaru tabulas daļÄ:
<U0020> IGNORE;IGNORE;IGNORE;<U0020> % SPACE
<U0021> IGNORE;IGNORE;IGNORE;<U0021> % EXCLAMATION MARK
<U0022> IGNORE;IGNORE;IGNORE;<U0022> % QUOTATION MARK
...
Redzams, ka Å”ajÄ tabulÄ pieturzÄ«mes no tabulas ASCII (ieskaitot atstarpi) gandrÄ«z vienmÄr tiek ignorÄts, salÄ«dzinot virknes. VienÄ«gie izÅÄmumi ir rindas, kas sakrÄ«t visÄs lietÄs, izÅemot pieturzÄ«mes, kas atrodamas atbilstoÅ”Äs pozÄ«cijÄs. Rindas no mana piemÄra (pÄc ŔķiroÅ”anas) salÄ«dzinÄÅ”anas algoritmam izskatÄs Å”Ädi:
ŠŠ±Š°ŠŗŠ°Š½Š¾Š²ŠŠøŃ
Š°ŠøŠ»Š¼Š°Š»ŃŃ
ŠŠ»ŠŗŠøŠ½Š°ŠŠ»Š»Š°ŠŗŃŠ°Š½Š¾Š²ŃŠøŃŠ°
ŠŠ²Š°Š½Š¾Š²Š°ŠŠ»Š»Š°Š¼Š°Š»ŃŃ
ŠŠ²Š°Š½Š¾Š²ŠŠ½Š“ŃŠµŠ¹ŃŠ»ŠµŃŠ°ŃŃ
Å emot vÄrÄ, ka skalu tabulÄ lielie burti krievu valodÄ nÄk aiz mazajiem burtiem (treÅ”ajÄ lÄ«menÄ« smagÄks par ), ŔķiroÅ”ana izskatÄs pilnÄ«gi pareiza.
Iestatot mainÄ«go LC_COLATE=C tiek ielÄdÄta Ä«paÅ”a tabula, kas norÄda baitu pa baitam salÄ«dzinÄjumu
static const uint32_t collseqwc[] =
{
8, 1, 8, 0x0, 0xff,
/* 1st-level table */
6 * sizeof (uint32_t),
/* 2nd-level table */
7 * sizeof (uint32_t),
/* 3rd-level table */
L'x00', L'x01', L'x02', L'x03', L'x04', L'x05', L'x06', L'x07',
L'x08', L'x09', L'x0a', L'x0b', L'x0c', L'x0d', L'x0e', L'x0f',
...
L'xf8', L'xf9', L'xfa', L'xfb', L'xfc', L'xfd', L'xfe', L'xff'
};
TÄ kÄ Unicode koda punkts Š ir pirms A, virknes tiek sakÄrtotas atbilstoÅ”i.
Teksta un binÄrÄs tabulas
AcÄ«mredzot virkÅu salÄ«dzinÄÅ”ana ir ÄrkÄrtÄ«gi izplatÄ«ta darbÄ«ba un tabulas parsÄÅ”ana CTT diezgan dÄrga procedÅ«ra. Lai optimizÄtu piekļuvi tabulai, tÄ tiek apkopota binÄrÄ formÄ ar komandu localdef.
Komanda localdef pieÅem kÄ parametrus failu ar nacionÄlo raksturlielumu tabulu (opcija -i), kurÄ visas rakstzÄ«mes attÄlo unikoda punkti, un atbilstÄ«bas fails starp Unikoda punktiem un noteikta kodÄjuma rakstzÄ«mÄm (opcija -f). Darba rezultÄtÄ tiek izveidoti binÄrie faili lokalizÄcijai ar nosaukumu, kas norÄdÄ«ts pÄdÄjÄ parametrÄ.
glibc atbalsta divus binÄros failu formÄtus: "tradicionÄlo" un "moderno".
TradicionÄlais formÄts nozÄ«mÄ, ka lokalizÄcijas nosaukums ir apakÅ”direktorija nosaukums /usr/lib/locale/. Å ajÄ apakÅ”direktorijÄ tiek glabÄti binÄrie faili LC_COLATE, LC_CTYPE, LC_TIME un tÄ tÄlÄk. Fails LC_IDENTIFICATION satur formÄlo lokalizÄcijas nosaukumu (kas var atŔķirties no direktorija nosaukuma) un komentÄrus.
MÅ«sdienu formÄts ietver visu lokalizÄciju glabÄÅ”anu vienÄ arhÄ«vÄ /usr/lib/locale/locale-archive, kas tiek kartÄta uz visu procesu virtuÄlo atmiÅu, kas tiek izmantota glibc. MÅ«sdienu formÄta lokalizÄcijas nosaukums ir pakļauts zinÄmai kanonizÄcijai - kodÄjuma nosaukumos paliek tikai cipari un burti, kas samazinÄti lÄ«dz mazajiem burtiem. TÄtad ru_RU.KOI8-R, tiks saglabÄts kÄ ru_RU.koi8r.
Ievades faili tiek meklÄti paÅ”reizÄjÄ direktorijÄ, kÄ arÄ« direktorijos /usr/share/i18n/locales/ Šø /usr/share/i18n/charmaps/ failiem CTT un kodÄÅ”anas faili, attiecÄ«gi.
PiemÄram, komanda
localedef -i ru_RU -f MAC-CYRILLIC ru_RU.MAC-CYRILLIC
apkopos failu /usr/share/i18n/locales/ru_RU izmantojot kodÄÅ”anas failu /usr/share/i18n/charmaps/MAC-CYRILLIC.gz un saglabÄjiet rezultÄtu /usr/lib/locale/locale-archive zem nosaukuma ru_RU.maccyrillic
Ja iestatÄt mainÄ«go LANG = en_US.UTF-8 ka glibc meklÄs lokalizÄcijas binÄros failus Å”ÄdÄ failu un direktoriju secÄ«bÄ:
/usr/lib/locale/locale-archive
/usr/lib/locale/en_US.UTF-8/
/usr/lib/locale/en_US/
/usr/lib/locale/enUTF-8/
/usr/lib/locale/en/
Ja lokalizÄcija notiek gan tradicionÄlajÄ, gan modernajÄ formÄtÄ, tad prioritÄte tiek dota modernajam.
Ar komandu var apskatÄ«t apkopoto lokalizÄciju sarakstu locale-a.
SalÄ«dzinÄÅ”anas tabulas sagatavoÅ”ana
Tagad, apbruÅojies ar zinÄÅ”anÄm, varat izveidot savu ideÄlo virkÅu salÄ«dzinÄÅ”anas tabulu. Å ajÄ tabulÄ pareizi jÄsalÄ«dzina krievu burti, ieskaitot burtu Š, un tajÄ paÅ”Ä laikÄ jÄÅem vÄrÄ pieturzÄ«mes saskaÅÄ ar tabulu ASCII.
Savas ŔķiroÅ”anas tabulas sagatavoÅ”anas process sastÄv no diviem posmiem: svaru tabulas rediÄ£ÄÅ”ana un kompilÄÅ”ana binÄrÄ formÄ ar komandu localdef.
Lai salÄ«dzinÄÅ”anas tabula tiktu koriÄ£Äta ar minimÄlÄm rediÄ£ÄÅ”anas izmaksÄm, formÄtÄ ISO 14652 Ir paredzÄtas sadaļas esoÅ”Ä galda svaru regulÄÅ”anai. Sadaļa sÄkas ar atslÄgvÄrdu pÄrkÄrtot pÄc un norÄdot pozÄ«ciju, pÄc kuras tiek veikta nomaiÅa. Sadaļa beidzas ar lÄ«niju pÄrkÄrtot-beigas. Ja nepiecieÅ”ams labot vairÄkas tabulas sadaļas, tad katrai Å”Ädai sadaļai tiek izveidota sadaļa.
Es nokopÄju jaunas failu versijas iso14651_t1_common Šø ru_ru no krÄtuves glibc uz manu mÄjas direktoriju ~/.local/share/i18n/locales/ un nedaudz rediÄ£Äju sadaļu LC_COLATE Š² ru_ru. JaunÄs failu versijas ir pilnÄ«bÄ saderÄ«gas ar manu versiju glibc. Ja vÄlaties izmantot vecÄkas failu versijas, tabulÄ bÅ«s jÄmaina simboliskie nosaukumi un vieta, kur sÄkas aizstÄÅ”ana.
LC_COLLATE
% Copy the template from ISO/IEC 14651
copy "iso14651_t1"
reorder-after <U000D>
<U0020> <S0020>;<BASE>;<MIN>;<U0020> % SPACE
<U0021> <S0021>;<BASE>;<MIN>;<U0021> % EXCLAMATION MARK
<U0022> <S0022>;<BASE>;<MIN>;<U0022> % QUOTATION MARK
...
<U007D> <S007D>;<BASE>;<MIN>;<U007D> % RIGHT CURLY BRACKET
<U007E> <S007E>;<BASE>;<MIN>;<U007E> % TILDE
reorder-end
END LC_COLLATE
PatiesÄ«bÄ bÅ«tu nepiecieÅ”ams mainÄ«t laukus LC_IDENTIFICATION lai tie norÄdÄ«tu uz lokalizÄciju ru_MY, bet manÄ piemÄrÄ tas nebija nepiecieÅ”ams, jo es izslÄdzu arhÄ«vu no lokalizÄciju meklÄÅ”anas lokalizÄcija-arhÄ«vs.
Ka localdef strÄdÄju ar failiem manÄ mapÄ, izmantojot mainÄ«go I18NPATH Varat pievienot papildu direktoriju, lai meklÄtu ievades failus, un direktoriju binÄro failu saglabÄÅ”anai var norÄdÄ«t kÄ ceļu ar slÄ«psvÄ«trÄm:
$> I18NPATH=~/.local/share/i18n localedef -i ru_RU -f UTF-8 ~/.local/lib/locale/ru_MY.UTF-8
POSIX pieÅem, ka iekÅ” VALODA jÅ«s varat rakstÄ«t absolÅ«tos ceļus uz direktorijiem ar lokalizÄcijas failiem, sÄkot ar slÄ«psvÄ«tru, bet glibc Š² Linux visi ceļi tiek skaitÄ«ti no bÄzes direktorija, kuru var ignorÄt, izmantojot mainÄ«go LOCPATH. PÄc uzstÄdÄ«Å”anas LOCPATH=~/.local/lib/locale/ visi ar lokalizÄciju saistÄ«tie faili tiks meklÄti tikai manÄ mapÄ. LokalizÄciju arhÄ«vs ar mainÄ«go komplektu LOCPATH ignorÄts.
Å eit ir izŔķiroÅ”ais pÄrbaudÄ«jums:
$> LANG=ru_MY.UTF-8 LOCPATH=~/.local/lib/locale/ sort buhg.txt
ŠŠ±Š°ŠŗŠ°Š½Š¾Š² ŠŠøŃ
Š°ŠøŠ»;Š¼Š°Š»ŃŃ
ŠŠ»ŠŗŠøŠ½Š° ŠŠ»Š»Š°;ŠŗŃŠ°Š½Š¾Š²ŃŠøŃŠ°
ŠŠ²Š°Š½Š¾Š² ŠŠ½Š“ŃŠµŠ¹;ŃŠ»ŠµŃŠ°ŃŃ
ŠŠ²Š°Š½Š¾Š²Š° ŠŠ»Š»Š°;Š°Š“Š²Š¾ŠŗŠ°Ń
UrrÄ! MÄs to izdarÄ«jÄm!
Dažas kļūdas
Uz sÄkumÄ uzdotajiem jautÄjumiem par virkÅu ŔķiroÅ”anu jau atbildÄju, bet vÄl ir pÄris jautÄjumi par kļūdÄm - redzamÄm un neredzamÄm.
AtgriezÄ«simies pie sÄkotnÄjÄs problÄmas.
Un programma Ŕķirot un programmu pievienoties izmantojiet tÄs paÅ”as virkÅu salÄ«dzinÄÅ”anas funkcijas no glibc. KÄ tas notika pievienoties radÄ«ja kÄrtoÅ”anas kļūdu rindÄs, kas sakÄrtotas pÄc komandas Ŕķirot lokalizÄcijÄ lv_US.UTF-8? Atbilde ir vienkÄrÅ”a: Ŕķirot salÄ«dzina visu virkni un pievienoties salÄ«dzina tikai atslÄgu, kas pÄc noklusÄjuma ir virknes sÄkums lÄ«dz pirmajai atstarpes rakstzÄ«mei. ManÄ piemÄrÄ tika parÄdÄ«ts kļūdas ziÅojums, jo pirmo vÄrdu kÄrtoÅ”ana rindÄs neatbilda visu rindu ŔķiroÅ”anai.
LokalizÄcija "C" garantÄ, ka sakÄrtotajÄs virknÄs tiks sakÄrtotas arÄ« sÄkotnÄjÄs apakÅ”virknes lÄ«dz pirmajai atstarpei, taÄu tas tikai maskÄ kļūdu. Ir iespÄjams atlasÄ«t datus (cilvÄkus ar vienÄdiem uzvÄrdiem, bet dažÄdiem vÄrdiem), kas bez kļūdas ziÅojuma dotu nepareizu failu sapludinÄÅ”anas rezultÄtu. Ja mÄs vÄlamies pievienoties apvienotas faila rindas pÄc pilna nosaukuma, tad pareizais veids bÅ«tu skaidri norÄdÄ«t lauku atdalÄ«tÄju un kÄrtot pÄc atslÄgas lauka, nevis pÄc visas rindas. Å ÄdÄ gadÄ«jumÄ sapludinÄÅ”ana noritÄs pareizi, un nevienÄ lokalizÄcijÄ nebÅ«s kļūdu:
$> sort -t ; -k 1 buhg.txt > buhg.srt
$> sort -t ; -k 1 mail.txt > mail.srt
$> join -t ; buhg.srt mail.srt > result
VeiksmÄ«gi izpildÄ«ts kodÄÅ”anas piemÄrs CP1251 satur citu kļūdu. Fakts ir tÄds, ka visos man zinÄmajos izplatÄ«jumos Linux pakotnÄm trÅ«kst kompilÄtÄs lokalizÄcijas ru_RU.CP1251. Ja kompilÄtÄ lokalizÄcija nav atrasta, tad Ŕķirot klusi izmanto baitu pa baitam salÄ«dzinÄjumu, ko mÄs novÄrojÄm.
Starp citu, ir vÄl viena neliela kļūme, kas saistÄ«ta ar kompilÄto lokalizÄciju nepieejamÄ«bu. Komanda LOCPATH=/tmp lokalizÄcija -a sniegs visu lokalizÄciju sarakstu lokalizÄcija-arhÄ«vs, bet ar mainÄ«go kopu LOCPATH visÄm programmÄm (ieskaitot lielÄko daļu locale) Ŕīs lokalizÄcijas nebÅ«s pieejamas.
$> LOCPATH=/tmp locale -a | grep en_US
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_MESSAGES to default locale: No such file or directory
locale: Cannot set LC_COLLATE to default locale: No such file or directory
en_US
en_US.iso88591
en_US.iso885915
en_US.utf8
$> LC_COLLATE=en_US.UTF-8 sort --debug
sort: using āen_US.UTF-8ā sorting rules
$> LOCPATH=/tmp LC_COLLATE=en_US.UTF-8 sort --debug
sort: using simple byte comparison
SecinÄjums
Ja esat programmÄtÄjs, kurÅ” ir pieradis domÄt, ka virknes ir baitu kopa, tad jÅ«su izvÄle LC_COLATE=C.
Ja esat valodnieks vai vÄrdnÄ«cu sastÄdÄ«tÄjs, labÄk kompilÄjiet savÄ lokalizÄcijÄ.
Ja esat vienkÄrÅ”s lietotÄjs, tad jums vienkÄrÅ”i jÄpierod pie tÄ, ka komanda ls -a izvada failus, kas sÄkas ar punktu, kas sajaukti ar failiem, kas sÄkas ar burtu un Pusnakts komandieris, kas izmanto savas iekÅ”ÄjÄs funkcijas, lai kÄrtotu nosaukumus, saraksta sÄkumÄ ievieto failus, kas sÄkas ar punktu.
atsauces
Avots: www.habr.com