Portál AbcLinuxu, 23. dubna 2024 11:44

Kódování textu

30. 10. 2009 | David Watzke
Články - Kódování textu  

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í.

Obsah

Co je to kódování textu?

link

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ů.

Konce řádků

link

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, mac2unixunix2dos.

dos2unix soubor_z_windows.txt soubor_z_linuxu.txt

Automatická detekce kódování a Enca

link

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

link

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

GNU Recode

link

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 <<< '&amp;&ndash;&amp;'
&–&

cstocs

link

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.

convmv

link

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í.

Závěr

link

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
ěščřžýáíé

Související články

Seriál: Unixové nástroje
Seriál: BASH
Regulární výrazy
Bash: chytré doplňování

Další články z této rubriky

VDR a DVB-T2, část 2.
VDR a DVB-T2, část 1.
Šifrovaný Proxmox VE 6: ZFS, LUKS, systemd_boot a Dropbear
MapTiler – proměňte obrázek v zoomovatelnou mapu
Syncthing

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.