GNU/Linux >> Linux Esercitazione >  >> Linux

Linux:come rendere Tr consapevole dei caratteri non ascii (unicode)?

Sto cercando di rimuovere alcuni caratteri dal file (UTF-8). Sto usando tr a questo scopo:

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

Il file contiene alcuni caratteri stranieri (come "Латвийская" o "àé"). tr sembra non capirli:li tratta come non alfa e li rimuove anche.

Ho provato a modificare alcune delle mie impostazioni internazionali:

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

Sfortunatamente, nessuno di questi ha funzionato.

Come posso creare tr capisci Unicode?

Risposta accettata:

Questa è una limitazione nota (1, 2, 3, 4, 5, 6) dell'implementazione GNU di tr .

Non è tanto che non supporti stranieri , caratteri non inglesi o non ASCII, ma che non supporta i caratteri multibyte.

Quei caratteri cirillici verrebbero trattati correttamente, se scritti nel set di caratteri iso8859-5 (byte singolo per carattere) (e la tua locale stava usando quel set di caratteri), ma il tuo problema è che stai usando UTF-8 dove non ASCII i caratteri sono codificati in 2 o più byte.

GNU ha un piano (vedi anche) per risolvere il problema e il lavoro è in corso ma non ancora.

FreeBSD o Solaris tr non avere il problema.

Nel frattempo, per la maggior parte dei casi d'uso di tr , puoi usare GNU sed o GNU awk che supportano i caratteri multibyte.

Ad esempio, il tuo:

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

potrebbe essere scritto:

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

oppure:

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

Per convertire tra lettere minuscole e maiuscole (tr '[:upper:]' '[:lower:]' ):

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

(che l è una L minuscola , non il 1 cifra).

oppure:

gawk '{print tolower($0)}'

Per la portabilità, perl è un'altra alternativa:

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

Se sai che i dati possono essere rappresentati in un set di caratteri a byte singolo, puoi elaborarli in quel set di caratteri:

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

Linux
  1. Come rendere di nuovo utile un vecchio computer

  2. Linux:come rendere un processo invisibile agli altri utenti?

  3. Come scrivo caratteri non ASCII usando echo?

  4. Come creare un pacchetto di test Travis CI per Linux, OS X, Windows?

  5. Come eseguire il backup differenziale in Linux?

Come rendere eseguibile un file in Linux

Come realizzare una USB multiboot in Linux e Windows

Come Linux può semplificarti la vita

Come rimuovere (^M) caratteri da un file in Linux

Come rendere eseguibile un file nel terminale Linux?

Come creare un server Minecraft su distribuzioni Linux