ファイル(UTF-8)から一部の文字を削除しようとしています。私はこの目的のためにtr
を使用しています:
tr -cs '[[:alpha:][:space:]]' ' ' <testdata.dat
ファイルにいくつかの外来文字(「Латвийская」や「àé」など)が含まれています。 tr
はそれらを理解していないようです:それらを非アルファとして扱い、削除します。
ロケール設定の一部を変更しようとしました:
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
残念ながら、どれもうまくいきませんでした。
tr
にUnicodeを理解させるにはどうすればよいですか?
それは既知です( 1 、 2 、、 4 、 5 、- 6 )GNU tr
の実装の制限。
foreign、英語以外の文字、またはASCII以外の文字はサポートしていませんが、マルチバイト文字はサポートしていません。 。
これらのキリル文字は、iso8859-5(文字あたり1バイト)文字セット(およびロケールがその文字セットを使用していた)で記述されていれば問題なく処理されますが、問題は、ASCII以外の場所でUTF-8を使用していることです。文字は2バイト以上にエンコードされます。
GNUはそれを修正するために プラン ( also を参照)を得ており、作業は進行中ですが、まだそこにはありません。
FreeBSDまたはSolaris tr
には問題はありません。
それまでの間、tr
のほとんどの使用例では、GNU sedまたはGNU awkでマルチバイト文字をサポートしています)を使用できます。 。
たとえば、あなたの:
tr -cs '[[:alpha:][:space:]]' ' '
書くことができます:
gsed -E 's/( |[^[:space:][:alpha:]])+/ /'
または:
gawk -v RS='( |[^[:space:][:alpha:]])+' '{printf "%s", sep $0; sep=" "}'
小文字と大文字を変換するには(tr '[:upper:]' '[:lower:]'
):
gsed 's/[[:upper:]]/\l&/g'
(l
は小文字のL
であり、1
の数字ではありません)。
または:
gawk '{print tolower($0)}'
移植性のために、Perl
は別の代替手段です。
Perl -Mopen=locale -pe 's/([^[:space:][:alpha:]]| )+/ /g'
Perl -Mopen=locale -pe '$_=lc$_'
データが1バイト文字セットで表現できることがわかっている場合は、その文字セットで処理できます。
(export LC_ALL=ru_RU.iso88595
iconv -f utf-8 |
tr -cs '[:alpha:][:space:]' ' ' |
iconv -t utf-8) < Russian-file.utf8