Snažím se odstranit některé znaky ze souboru (UTF-8). Používám tr
pro tento účel:
tr -cs '[[:alpha:][:space:]]' ' ' <testdata.dat
Soubor obsahuje některé cizí znaky (např. „Латвийская“ nebo „àé“). tr
Zdá se, že jim nerozumí:považuje je za nealfa a také je odstraňuje.
Pokusil jsem se změnit některá nastavení národního prostředí:
LC_CTYPE=C LC_COLLATE=C tr -cs '[[:alpha:][:space:]]' ' ' <testdata.dat
LC_CTYPE=ru_RU.UTF-8 LC_COLLATE=C tr -cs '[[:alpha:][:space:]]' ' ' <testdata.dat
LC_CTYPE=ru_RU.UTF-8 LC_COLLATE=ru_RU.UTF-8 tr -cs '[[:alpha:][:space:]]' ' ' <testdata.dat
Bohužel nic z toho nefungovalo.
Jak mohu vytvořit tr
rozumíte Unicode?
Přijatá odpověď:
To je známé (1, 2, 3, 4, 5, 6) omezení GNU implementace tr
.
Není to tak, že nepodporuje zahraniční , neanglické nebo jiné než ASCII znaky, ale že nepodporuje vícebajtové znaky.
S těmito znaky azbuky by se zacházelo OK, pokud by byly zapsány ve znakové sadě iso8859-5 (jeden bajt na znak) (a vaše národní prostředí tuto znakovou sadu používalo), ale váš problém je v tom, že používáte UTF-8, kde není ASCII znaky jsou zakódovány ve 2 nebo více bajtech.
GNU má plán (viz také), jak to napravit a práce probíhají, ale zatím to není.
FreeBSD nebo Solaris tr
nemají problém.
Mezitím pro většinu případů použití tr
, můžete použít GNU sed nebo GNU awk, které podporují vícebajtové znaky.
Například vaše:
tr -cs '[[:alpha:][:space:]]' ' '
by se dalo napsat:
gsed -E 's/( |[^[:space:][:alpha:]])+/ /'
nebo:
gawk -v RS='( |[^[:space:][:alpha:]])+' '{printf "%s", sep $0; sep=" "}'
Převod mezi malými a velkými písmeny (tr '[:upper:]' '[:lower:]'
):
gsed 's/[[:upper:]]/l&/g'
(to l
je malé písmeno L
, nikoli 1
číslice).
nebo:
gawk '{print tolower($0)}'
Pro přenositelnost perl
je další alternativou:
perl -Mopen=locale -pe 's/([^[:space:][:alpha:]]| )+/ /g'
perl -Mopen=locale -pe '$_=lc$_'
Pokud víte, že data mohou být reprezentována jednobajtovou znakovou sadou, můžete je zpracovat v této znakové sadě:
(export LC_ALL=ru_RU.iso88595
iconv -f utf-8 |
tr -cs '[:alpha:][:space:]' ' ' |
iconv -t utf-8) < Russian-file.utf8