Portál AbcLinuxu, 23. dubna 2024 11:44
V tomto článku si povíme něco o problematice kódování textu a představíme si několik nástrojů sloužících ke konverzi (a detekci) kódování (Enca, iconv, GNU Recode, cstocs, convmv), to vše doplněno o příklady použití.
V IT jde o způsob reprezentace znaků pomocí sekvence přirozených čísel nebo bajtů. K čemu to? Protože počítač nekomunikuje abecedou :-). Nejzákladnějším příkladem je 7bitová znaková sada ASCII, která obsahuje znaky anglické abecedy plus další v informatice využívané znaky. Znaků je celkem 128, což vyplývá ze zmiňovaných 7 bitů, protože 2 ^ 7 = 128. Jenže 128 znaků je málo pro obsažení ostatních abeced a dalších znaků, a proto vznikla další kódování, například různá 8bitová rozšíření ASCII (pro češtinu zejména Windows 1250, ISO 8859-2, CP852) s 256 znaky. I toto ovšem bylo málo, a proto bylo vyvinuto kódování Unicode, jehož patrně nejpoužívanější variantou je UTF-8.
Předpokládám, že je vám asi jasné, co za nejrůznější problémy to přináší. Setkal se s tím snad každý. Nejčastěji když například autor webových stránek zapomene uvést kódování v HTML hlavičce a vy pak místo českých znaků vidíte nějaký paskvil. To je tím, že se kódovaný text převádí do námi čitelné podoby pomocí špatné znakové sady.
V následujících odstavcích si předvedeme různé programy sloužící k převodu kódování textu a jeden, který umí opravit špatně kódované názvy souborů.
Dokonce ani na znaku symbolizujícím nový řádek se tvůrci operačních systémů neshodli. Microsoft používá CR+LF (nebo-li \r\n
v C), Apple až do doby Mac OS 9 používal CR (\r
) a UN*X systémy (včetně Linuxu a Mac OS X) používají LF (\n
). I na to je třeba dávat pozor, v praxi na to člověk narazí třeba při spouštění shellového skriptu s CR+LF konci řádků:
$ ./CRLF.sh bash: ./CRLF.sh: /bin/bash^M: bad interpreter: Adresář nebo soubor neexistuje
Naštěstí to není tak velký problém a poslouží nám zde nástroje dos2unix
, mac2unix
a unix2dos
.
dos2unix soubor_z_windows.txt soubor_z_linuxu.txt
Kódování někdy nelze strojově detekovat tak snadno, jak by si někdo mohl myslet. Je zde mnoho háčků, jako třeba podobnost některých kódování, a také to, že je jich opravdu mnoho. Nicméně existují projekty, které se tímto zabývají a jedním z nich je Enca, která má mimochodem původ v ČR a jejím původním autorem je David Nečas (Yeti), který kdysi působil i zde na AbcLinuxu.
Abych encu vyzkoušel, zkusil jsem pomocí níže jmenovaných programů vytvořit pár souborů s textem ěščřžýáíé v různém kódování.
$ enca utf8.txt Universal transformation format 8 bits; UTF-8 $ enca iso8859-2.txt ISO 8859-2 standard; ISO Latin 2 $ enca cp1250.txt MS-Windows code page 1250 $ enca cp852.txt IBM/MS code page 852; PC (DOS) Latin 2
Enca umí vypsat kódování i ve formátu vhodném pro iconv (přepínač -i), cstocs (-s) nebo podle RFC 1345 (-r).
$ enca -r ~/abcl/kodovani.html UTF-8
Detekce evidentně funguje dobře. Enca umí i převádět kódování (pomocí nástroje enconv
), a to buď vestavěným rozhraním nebo pomocí externích knihoven a nástrojů (libiconv, librecode, cstocs – viz níže). Zkusil jsem testovací soubory převést zpátky na UTF-8 s tím, že jsem nechal encu detektovat vstupní kódování a ani zde nebyl problém. Při převodu z windowsích kódování Enca automaticky ukončuje řádky windowsím stylem (CRLF).
$ enconv -x utf8 < cp1250.txt ěščřžýáíé
Pokud chcete místo vestavěného převodníku použít jiný podporovaný, nechte se inspirovat následující ukázkou:
# použije externí program, výchozí je cstocs, lze nastavit přes -E enconv -x cp1250 -C extern < ~/abcl/kodovani.html # použije libiconv enconv -x cp1250 -C iconv < soubor.txt # použije librecode enconv -x cp1250 -C librecode < ../jiny_soubor.txt
iconv
je program (a API) sloužící k převodu kódování textu. Je součástí standardu Single UNIX Specification. Poprvé se objevil na systému HP-UX. Na GNU/Linuxu je dostupná svobodná implementace v glibc, což je standardní knihovna programovacího jazyka C od GNU.
Nyní si předvedeme ukázku použití. Pro vypsání všech známých kódování spusťte:
iconv -l
Jelikož iconv
dokáže pracovat jak se standardním vstupem a výstupem, tak se soubory, můžete dle potřeby použít přesměrování shellu, roury nebo přímo rozhraní programu. Oba následující příkazy provedou to samé; převedou text z kódování Windows 1250 na UTF-8.
iconv -f cp1250 -t utf8 < cp1250-vstup.txt > utf8-vystup.txt iconv -f cp1250 -t utf8 cp1250-vstup.txt -o utf8-vystup.txt
Projekt Recode je též knihovna i program (recode
). Umí využívat iconv a podporuje tak až 300 různých kódování.
# změní kódování souboru „soubor.txt“ z UTF-8 na Windows 1250 recode utf8..cp1250 soubor.txt # nebo když nechcete přepsat původní soubor: recode utf8..cp1250 < soubor.txt > jiny_soubor.txt
Recode podporuje nejen znakové sady, ale i různé fajnovosti jako třeba HTML nebo TeX.
$ recode html..utf8 <<< '&–&' &–&
Cstools obsahují dva perlové moduly + nástroj cstocs
. Jde o projekt z české dílny a slouží, podobně jako ostatní výše zmiňované nástroje, ke konverzi znakové sady textu. Použití vypadá následovně:
# cstocs [-i] vstupni_kodovani vystupni_kodovani [soubor(y)] # převod cp1250 na UTF-8 cstocs 1250 utf8 < vstup-v-cp1250.txt > vystup-v-utf8.txt # převede soubor.txt z UTF-8 na ISO 8859-2 cstocs -i utf8 iso8859-2 soubor.txt
Pokud vstupní kódování obsahuje znak, který není ve výstupní znakové sadě, můžete nastavit, jak se má program zachovat. Například --null tyto znaky vynechá a --fillstring="?" je nahradí za otazník.
Perlový nástroj convmv
slouží k převodu kódování názvů souborů. Něco takového je třeba, když si do Linuxu zkopírujete soubor z Windows nebo takto (nedejbože) něco přímo stáhnete. Uživatelé Windows například rádi posílají přílohy s diakritikou v názvu. Ať už jste se do této situace dostali jakkoliv, tak vězte, že praktické použití vypadá následovně:
$ convmv -f cp1250 -t utf8 . Starting a dry run without changes… mv "./KOM V�KLAD-1.pol.IV.r.-08.doc" "./KOM VÝKLAD-1.pol.IV.r.-08.doc" No changes to your files done. Use --notest to finally rename the files.
Přepínači -f zadáte jako parametr vstupní kódování, -t výstupní a nakonec uvedete soubory či adresáře. Případně přidáte -r pro rekurzivní procházení adresářů. Toto spustíte, prohlédnete si, co se bude dít, a když vám to vyhovuje, tak teprve poté spustíte totéž navíc s přepínačem --notest, se kterým program soubory již skutečně přejmenuje.
$ convmv -r -f cp1250 -t utf8 . --notest mv "./KOM V�KLAD-1.pol.IV.r.-08.doc" "./KOM VÝKLAD-1.pol.IV.r.-08.doc" Ready!
Po tomhle mi už nezbývá, než doporučit odstranit diakritiku z názvů úplně. Přináší to akorát problémy s přenositelností.
Který z nástrojů na konverzi znakové sady textu si vyberete, to je na vás. Vězte, že v tom, co spolu mají společné, fungují stejně.
$ cat utf8.txt ěščřžýáíé $ cstocs utf8 1250 utf8.txt | iconv -f cp1250 -t utf8 | \ recode utf8..cp1250 | enconv ěščřžýáíé
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.