Abecední řazení v Linuxu (LC_COLLATE)
Martin Edlman
edlman na fortech.cz
Pondělí Duben 26 09:52:28 CEST 2010
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Zdravím,
hledáním na Netu jsem nakonec našel řešení, na stejný problém se řazením
mezery si stěžují také Poláci, Španělé a další.
Snad se bude následující návod hodit i dalším. Následující popis funguje
na RH EL a Fedoře, jiný distro jsem nezkoušel.
Nejprve upravíme definice v textovým souboru
/usr/share/i18n/locales/cs_CZ, najdeme řádek <U0020>
IGNORE;IGNORE;IGNORE;<U0020>, který říká, že se má mezera v prvních
třech krocích ignorovat a ve čtvrtém použít. Tento řádek změníme na
<U0020> <U0020>;IGNORE;<U0020>;<U0020> (tuto definici jsem našel někde
na Inetu jako patch do pl_PL definic - problém s mezerou je nejen v
cs_CZ, ale téměř ve všech locale).
Potom je třeba vyhodit z archivu cs_CZ definice, překompilovat je a
znovu vložit do archivu.
# vypíšeme české definice, mělo by být cs_CZ, cs_CZ.utf8, cs_CZ.iso88592
localedef --list-archive | grep cs_CZ
# smažeme z archivu definice
localedef --delete-from-archive cs_CZ
localedef --delete-from-archive cs_CZ.utf8
localedef --delete-from-archive cs_CZ.iso88592
# vytvoříme novou binární podobu z textové definice
localedef -i /usr/share/i18n/locales/cs_CZ -f UTF-8 \
/usr/lib/locale/cs_CZ
localedef -i /usr/share/i18n/locales/cs_CZ -f UTF-8 \
/usr/lib/locale/cs_CZ.UTF-8
localedef -i /usr/share/i18n/locales/cs_CZ -f ISO-8859-2 \
/usr/lib/locale/cs_CZ.ISO-8859-2
# vytvoříme novou binární podobu z textové definice
localedef --add-to-archive cs_CZ
localedef --add-to-archive cs_CZ.UTF-8
localedef --add-to-archive cs_CZ.ISO-8859-2
# vypíšeme české definice, mělo by být cs_CZ, cs_CZ.utf8, cs_CZ.iso88592
localedef --list-archive | grep cs_CZ
No a teď by mělo být řazení v pořádku.
> narazil jsem v PostgreSQL na problém se řazením, jak jsem následně
> zjistil, není to problém PgSQL ale locale v systému (příkaz sort se
> chová stejně jako order by v PgSQL).
>
> Chci seřadit Zdvořilý, Zdražil, ZD Písek
> Očekávám ZD Písek, Zdražil, Zdvořilý
> Dostanu Zdražil, ZD Písek, Zdvořilý
>
> Tedy mezera v ZD Písek se ignoruje a řadí se jako ZDPísek.
>
> Řazení je ovlivněno nastavením LC_COLLATE, popř. LANG. V definičním
> souboru /usr/share/i18n/locales/cs_CZ jsem našel poznámku
>
> % Odlišnosti od normy:
> % ....
> % 3.2:
> % Mezera se řadí před první písmeno abecedy, ale každý znak mezery je
> % uvažován samostatně. Toto pravidlo je uplatněno na hesla, která jsou
> % si jinak rovna (v prvních třech průchodech).
>
> Pokud tomu rozumím, tak se mezera uvažuje až při shodě, takže ZD Písek
> by se zařadil před ZDPísek (bez mezery shoda, mezera jde tedy dopředu).
>
> Je možné změnit nějak jednoduše chování řazení? Lze něco změnit v
> uvedeném souboru a překompilovat ho? Zkoušel jsem měnit řádek
>
> <U0020> IGNORE;IGNORE;IGNORE;<U0020>
>
> který by měl definovat chování na mezeře, ale byly to spíš jen takové
> náhodné pokusy, syntaxi toho souboru moc nechápu.
> Taky nevím jestli pak tento soubor zkompilovat, zkoušel jsem příkaz
>
> # localedef -i /usr/share/i18n/locales/cs_CZ /usr/share/locale/cs_CZ/
>
> ale sort se chová stále stejně, žádný náznak změny.
>
> Můžete mi prosím poradit?
- --
S pozdravem,
Martin Edlman
Fortech, spol. s r.o,
Ropkova 51, 57001 Litomyšl
Public GPG key: http://edas.visaci.cz/#gpgkeys
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/
iEYEARECAAYFAkvVRjwACgkQqmMakYm+VJ9FbACdF4HvPcDmPMV7/IujqTk6vDcJ
emEAoIkcdGd0Q8YoOORAO4KQXiBFIKad
=BoGu
-----END PGP SIGNATURE-----
Další informace o konferenci Linux