GNU/Linux >> Znalost Linux >  >> Linux

Tr Analog pro znaky Unicode?

Potřebuji internacionalizovaný nástroj, který dělá to samé jako tr :získá znak ze streamu a nahradí jej odpovídajícím znakem.
Nejedná se o řešení konkrétního případu jako od nižšího k hornímu, ale je potřeba obecné řešení případu.
Bez gorillion piped sed volání, pokud je to možné.

Všimněte si, že tr nefunguje na Linuxu:překládá bajty, nikoli znaky. Toto selhává u vícebajtových kódování.

$ tr --version | head -n 1
tr (GNU coreutils) 8.23
$ echo $LC_CTYPE
en_US.UTF-8
$ echo 'Ångstrom' | tr Æ Œ         
Ņngstrom

Přijatá odpověď:

GNU sed pracuje s vícebajtovými znaky. Takže:

$ echo é½Æ | sed 'y/é½Æ/ABŒ/'
ABŒ

Není to tak moc, že ​​GNU tr nebyl internacionalizován, ale že nepodporuje vícebajtové znaky (jako ty bez ASCII v národních prostředích UTF-8). GNU tr bude fungovat s Æ , Œ pokud byly jednobajtové jako ve znakové sadě iso8859-15.

Více o tom na Jak upozornit na ne-ascii (unicode) znaky?

V každém případě to nemá nic společného s Linuxem, je to o tr implementace v systému. Zda tento systém používá Linux jako jádro nebo tr je vytvořen pro Linux nebo používá linuxové jádro API není relevantní, protože tato část tr funkčnost se odehrává v uživatelském prostoru.

busybox tr a GNU tr se nejčastěji vyskytují v distribucích softwaru vytvořeného pro Linux a nepodporují vícebajtové znaky, ale existují i ​​jiné, které byly portovány na Linux, jako je tr z heirloom toolchest (portováno z OpenSolaris) nebo z ast-open, které to dělají.

Všimněte si, že sed 's y nepodporuje rozsahy jako a-z . Všimněte si také, že pokud tento skript obsahuje sed 'y/é½Æ/ABŒ/' je zapsán ve znakové sadě UTF-8, nebude již fungovat podle očekávání, pokud bude volán v národním prostředí, kde UTF-8 není znaková sada.

Alternativou může být použití perl :

perl -Mopen=locale -Mutf8 -pe 'y/a-zé½Æ/A-ZABŒ/'

Výše se očekává, že kód perl bude v UTF-8, ale zpracuje vstup v kódování národního prostředí (a výstup ve stejném kódování). Pokud je voláno v národním prostředí UTF-8, přepíše UTF-8 Æ (0xc3 0x86) na UTF-8 Œ (0xc5 0x92) a v ISO8859-15 stejné, ale pro 0xc6 -> 0xbc.

Ve většině shellů by mělo být umístění těchto znaků UTF-8 v jednoduchých uvozovkách v pořádku, i když je skript volán v národním prostředí, kde UTF-8 není znaková sada (výjimkou je yash což by si stěžovalo, pokud tyto bajty netvoří platné znaky v národním prostředí). Pokud však používáte jiné než jednoduché uvozovky, může to způsobit problémy. Například,

perl -Mopen=locale -Mutf8 -pe "y/♣`/&'/"

by selhal v národním prostředí, kde je znaková sada BIG5-HKSCS, protože kódování (0x5c) je shodou okolností obsaženo i v některých dalších znacích (například α :0xa3 0x5c a kódování UTF-8 náhodou končí 0xa3).

Související:Konfigurace analogového pinu PIC16F877?

V žádném případě nečekejte věci jako

perl -Mopen=locale -Mutf8 -pe 'y/Á-Ź/A-Z/'

pracovat na odstranění akutních akcentů. Výše uvedené je vlastně jen

perl -Mopen=locale -Mutf8 -pe 'y/x{c1}-x{179}/x{41}-x{5a}/'

To znamená, že rozsah je založen na kódových bodech unicode. Rozsahy tedy nebudou užitečné mimo velmi dobře definované sekvence, které jsou náhodou „správně ” pořadí v Unicode jako A-Z , 0-9 .

Pokud chcete odstranit ostré akcenty, budete muset použít pokročilejší nástroje, jako je:

perl -Mopen=locale -MUnicode::Normalize -pe '
  $_ = NFKD($_); s/x{301}//g; $_ = NFKC($_)'

To znamená použití normalizačních formulářů Unicode k rozložení znaků, odstranění ostrých akcentů (zde kombinační formulář U+0301 ) a znovu složte.

Dalším užitečným nástrojem pro přepis Unicode je uconv z JIP. Výše uvedené může být například také zapsáno jako:

uconv -x '::NFKD; u0301>; ::NFKC;'

I když by fungoval pouze na datech UTF-8. Budete potřebovat:

iconv -t utf-8 | uconv -x '::NFKD; u0301>; ::NFKC;' | iconv -f utf-8

Aby bylo možné zpracovávat data v národním prostředí uživatele.


Linux
  1. Jak skenovat neplatné znaky na Gedit?

  2. Převést heslo se speciálními znaky pro použití s ​​Expect Script?

  3. Jak převést \uXXXX unicode na UTF-8 pomocí konzolových nástrojů v *nix

  1. Proč wprintf v Linuxu přepisuje ruský text v Unicode do latinky?

  2. Co by mohlo způsobit podivné postavy ve Vimu?

  3. Existuje ekvivalent cd - pro cp nebo mv?

  1. Linux – Jak upozornit Tr na znaky, které nejsou v ASCII (unicode)?

  2. Regulární výraz pro hledání dvojitých znaků v Bash

  3. Jak grep pro unicode � ve skriptu bash