GNU/Linux >> Znalost Linux >  >> Linux

Používáte Uniq na Unicode Text?

Chci odstranit duplicitní řádky ze souboru se slovy syrského písma. Zdrojový soubor má 3 řádky, 1. a 3. jsou identické.

$ cat file.txt 
ܐܒܘܢ
ܢܗܘܐ
ܐܒܘܢ

Když použiji sort a uniq , výsledek předpokládá, že všechny 3 řádky jsou identické, což je špatně:

$ cat file.txt | sort | uniq -c
      3 ܐܒܘܢ

Nepomůže ani explicitní nastavení národního prostředí na syrštinu.

$ LC_COLLATE=syr_SY.utf8 cat file.txt | sort | uniq -c      
     3 ܐܒܘܢ

Proč by se to stalo?
Používám Kubuntu 18 a bash, pokud na tom záleží.

Přijatá odpověď:

GNU implementace uniq jako na Ubuntu, s -c , neuvádí počty sousedících identických řádky, ale počty souvislých řádků, které třídí stejně¹.

Většina mezinárodních lokalit na systémech GNU má tu chybu, že mnoho zcela nesouvisejících znaků bylo definováno se stejným pořadím řazení, protože jejich pořadí řazení není definováno vůbec. Většina ostatních OS zajišťuje, že všechny znaky mají odlišné pořadí řazení.

$ expr ܐ = ܒ
1

(expr ‘s = operátor pro argumenty, které nejsou číselné, vrátí 1, pokud jsou operandy seřazeny stejně, jinak 0).

Totéž platí pro ar_SY.UTF-8 nebo en_GB.UTF-8 .

To, co byste potřebovali, je národní prostředí, kde bylo těmto postavám přiděleno jiné pořadí řazení. Pokud by Ubuntu mělo národní prostředí pro syrský jazyk, dalo by se očekávat, že těmto znakům bude přiřazeno jiné pořadí řazení, ale Ubuntu takové lokality nemá.

Můžete se podívat na výstup locale -a pro seznam podporovaných lokalit. Další národní prostředí můžete povolit spuštěním dpkg-reconfigure locales jako root . Další národní prostředí můžete také definovat ručně pomocí localedef na základě definičních souborů v /usr/share/i18n/locales , ale nenajdete tam žádná data pro syrský jazyk.

Všimněte si, že v:

LC_COLLATE=syr_SY.utf8 cat file.txt | sort | uniq -c

Proměnnou LC_COLLATE nastavujete pouze pro cat příkaz (který neovlivňuje způsob, jakým vydává obsah souboru, cat nezajímá řazení ani kódování znaků, protože se nejedná o textový nástroj). Měli byste jej nastavit pro obě sort a uniq . Také byste měli nastavit LC_CTYPE do národního prostředí, které má znakovou sadu UTF-8.

Protože váš systém nemá syr_SY.utf8 locale, to je stejné jako použití C locale (výchozí národní prostředí).

Ve skutečnosti zde pravděpodobně chcete použít národní prostředí C nebo C.UTF-8.

V těchto národních prostředích je pořadí řazení založeno na bodu kódu, bodu kódu Unicode pro C.UTF-8, hodnotě bajtu pro C, ale nakonec je to stejné, jako má kódování znaků UTF-8 tuto vlastnost.

$ LC_ALL=C expr ܐ = ܒ
0
$ LC_ALL=C.UTF-8 expr ܐ = ܒ
0

Takže s:

(export LANG=ar_SY.UTF-8 LC_COLLATE=C.UTF-8 LANGUAGE=syr:ar:en
 unset LC_ALL
 sort <file | uniq -c)

Měli byste mít LC_CTYPE s UTF-8 jako znakovou sadu, pořadí řazení založené na bodu kódu a další nastavení relevantní pro váš region, takže například chybové zprávy v syrštině nebo arabštině, pokud GNU coreutils sort nebo uniq zprávy byly do těchto jazyků přeloženy (zatím nebyly).

Související:Jak označit více kontaktů pro odeslání stejného textu jako skrytá kopie – funkce, která existuje na Androidu?

Pokud vám na těch ostatních nezáleží jeho použití je stejně snadné (a také přenosnější):

<file LC_ALL=C sort | LC_ALL=C uniq -c

Nebo

(export LC_ALL=C; <file sort | uniq -c)

jak již @isaac ukázal.


Linux
  1. sort Příklady příkazů v Linuxu

  2. sort:příkaz nenalezen

  3. Jak odstranit duplicitní slova ze souboru prostého textu pomocí příkazu linux

  1. Jak spočítat počet jedinečných hodnot pole v textovém souboru odděleném tabulátory?

  2. Získejte konkrétní řádek z textového souboru pouze pomocí skriptu Shell

  3. Jak vložím text do 1. řádku souboru pomocí sed?

  1. Připojování textu na konec textového souboru?

  2. Třídit část souboru?

  3. Vytvářejte soubory pomocí příkazového řádku v Linuxu