シリア文字の単語を含むファイルから重複行を削除したい。ソースファイルには3行あり、1番目と3番目は同じです。
$ cat file.txt
ܐܒܘܢ
ܢܗܘܐ
ܐܒܘܢ
sort
を使用する場合 およびuniq
、結果は3行すべてが同一であると想定していますが、これは誤りです:
$ cat file.txt | sort | uniq -c
3 ܐܒܘܢ
ロケールをシリア語に明示的に設定しても効果はありません。
$ LC_COLLATE=syr_SY.utf8 cat file.txt | sort | uniq -c
3 ܐܒܘܢ
なぜそうなるのでしょうか?
必要に応じて、Kubuntu18とbashを使用しています。
承認された回答:
uniq
のGNU実装 Ubuntuで見つかったように、 -c
、隣接する同一の数を報告しません 行ですが、同じものを並べ替える連続した行の数¹。
GNUシステムのほとんどの国際ロケールには、ソート順がまったく定義されていないため、ほとんどの完全に無関係な文字が同じソート順で定義されているというバグがあります。他のほとんどのOSは、すべての文字の並べ替え順序が異なることを確認します。
$ expr ܐ = ܒ
1
( expr
の=
演算子は、数値ではない引数の場合、オペランドが同じようにソートされる場合は1を返し、そうでない場合は0を返します。
ar_SY.UTF-8
でも同じです またはen_GB.UTF-8
。
必要なのは、それらの文字に異なる並べ替え順序が与えられているロケールです。 Ubuntuにシリア語のロケールがある場合、それらの文字には異なる並べ替え順序が与えられていると予想できますが、Ubuntuにはそのようなロケールはありません。
locale -a
の出力を見ることができます サポートされているロケールのリストについては。 dpkg-reconfigure locales
を実行すると、より多くのロケールを有効にできます root
として 。 localeedef
を使用して、より多くのロケールを手動で定義することもできます / usr / share / i18n / locales
の定義ファイルに基づく 、ただし、シリア語のデータはありません。
次の点に注意してください:
LC_COLLATE=syr_SY.utf8 cat file.txt | sort | uniq -c
cat
のLC_COLLATE変数のみを設定しています コマンド(ファイルのコンテンツを出力する方法には影響しません、 cat
テキストユーティリティではないため、照合や文字エンコードについても気にしません)。両方のsort
に設定する必要があります およびuniq
。 LC_CTYPE
も設定する必要があります UTF-8文字セットがあるロケールへ。
システムにsyr_SY.utf8
がないため ロケール、これは C
を使用するのと同じです ロケール(デフォルトのロケール)。
実際、ここではCロケールまたはC.UTF-8がおそらく使用したいロケールです。
これらのロケールでは、照合順序はコードポイント、C.UTF-8のUnicodeコードポイント、Cのバイト値に基づいていますが、UTF-8文字エンコードがそのプロパティを持っているのと同じになります。
$ LC_ALL=C expr ܐ = ܒ
0
$ LC_ALL=C.UTF-8 expr ܐ = ܒ
0
だから:
(export LANG=ar_SY.UTF-8 LC_COLLATE=C.UTF-8 LANGUAGE=syr:ar:en
unset LC_ALL
sort <file | uniq -c)
文字セットとしてUTF-8を使用したLC_CTYPE、コードポイントに基づく照合順序、および地域に関連するその他の設定があるため、たとえば、GNU coreutils sort
> またはuniq
メッセージはそれらの言語に翻訳されていました(まだ翻訳されていません)。
これらのその他を気にしない場合 設定は、同じように簡単に(そしてよりポータブルに)使用できます:
<file LC_ALL=C sort | LC_ALL=C uniq -c
または
(export LC_ALL=C; <file sort | uniq -c)
@isaacがすでに示しているように。