Tr ascii olmayan (unicode) karakterlerden nasıl haberdar olunur?


36

Bazı karakterleri dosyadan kaldırmaya çalışıyorum (UTF-8). trBu amaç için kullanıyorum :

tr -cs '[[:alpha:][:space:]]' ' ' <testdata.dat 

Dosyada bazı yabancı karakterler var ("Латвийская" veya "àé" gibi). trOnları anlamış görünmüyor: Onları alfa olmayan olarak görür ve bunları da kaldırır.

Yerel ayarlarımın bazılarını değiştirmeyi denedim:

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

Ne yazık ki, bunların hiçbiri işe yaramadı.

trUnicode'u nasıl anlayabilirim?

Yanıtlar:


29

Bu GNU uygulamasının bilinen bir ( 1 , 2 , 3 , 4 , 5 , 6 ) sınırlamasıdır tr.

O kadar çok o desteklemediği değil yabancı , İngilizce olmayan veya ASCII olmayan karakterler, ancak çok baytlık karakterleri desteklemiyor.

Bu Kiril karakterleri, iso8859-5 (karakter başına tek bayt) karakter kümesinde (ve yerel ayarınız bu karakter kümesini kullanıyorsa) yazılmışsa Tamam olarak işlem görür, ancak sorununuz ASCII olmayan yerlerde UTF-8 kullanıyor olmanızdır. karakterler 2 veya daha fazla baytta kodlanır.

GNU’nun bunu düzeltmek için bir planı var ( ayrıca bakınız ) ve çalışma henüz devam etmedi.

FreeBSD veya Solaris'te trsorun yok.


Bu arada, çoğu kullanım için tr, çok baytlık karakterleri destekleyen GNU sed veya GNU awk kullanabilirsiniz.

Örneğin, sizin:

tr -cs '[[:alpha:][:space:]]' ' '

yazılmış olabilir:

gsed -E 's/( |[^[:space:][:alpha:]])+/ /'

veya:

gawk -v RS='( |[^[:space:][:alpha:]])+' '{printf "%s", sep $0; sep=" "}'

Küçük ve büyük harf ( tr '[:upper:]' '[:lower:]') arasında dönüştürmek için :

gsed 's/[[:upper:]]/\l&/g'

(bu rakam lküçük harf Ldeğil 1rakamdır).

veya:

gawk '{print tolower($0)}'

Taşınabilirlik perliçin başka bir alternatif:

perl -Mopen=locale -pe 's/([^[:space:][:alpha:]]| )+/ /g'
perl -Mopen=locale -pe '$_=lc$_'

Verilerin tek baytlık bir karakter kümesinde gösterilebileceğini biliyorsanız, o zaman bu karakter kümesinde işleyebilirsiniz:

(export LC_ALL=ru_RU.iso88595
 iconv -f utf-8 |
   tr -cs '[:alpha:][:space:]' ' ' |
   iconv -t utf-8) < Russian-file.utf8

1
Sorunuzu tr hakkındaki bilgiler yüzünden kabul ettim. Sorunu çözdüm ve nasıl çözüleceği konusundaki soruyu kaldırdım (bu nedenle tr arayanlar bazı trit problemler değil sadece tr hakkında bilgi bulacaklar). Çözümü de kaldırabilirseniz, artık gerekmediği için minnettar olurum.
MatthewRock 09:15

3
@MatthewRock Ben tuttum ama yeniden sağladım ve etrafta bir kelime vermenin aynı problemi olan insanlar için yararlı olacağı için daha genel hale getirdim.
Stéphane Chazelas 09:15

Kiril'in (geleneksel olarak) ISO 8859-5'te kodlandığı konusunda bir fikrin nereden buluyorsunuz? Hiç Unicode dışında bir Rus metnini gördünüz mü?
Incnis MRSI

9
@IncnisMrsi, burada önemli olan, ISO 8859-5'in Kiril karakterlerine sahip olan tekli bayt karakterlerinden biri olduğu. Yaygın kullanımda olup olmaması, burada önemsizdir. KOI-R veya window-1251 charset ile yerel ayarlarınız varsa, bunun yerine kullanın.
Stéphane Chazelas 09:15

@IncnisMrsi Web’deki Rusça hemen hemen her zaman UTF-8’de (veya bazen Windows-1251’de) kodlanır, ancak yalnızca birçok bayt kodlamanın acısını daha erken hissettiğimiz için. Sch57.ru/collect : İşte bir (yaklaşık 1998) (işlevsel olmayan) kodlama anahtarlayıcı ile bir web sayfası .
Alex Shpilkin
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.