
ソートされた一意のリストを取得する必要がある人を見るたびに、彼らは常にこれをsort | uniq
。私はそれが使用される例を見たことがありませんsort -u
。なぜできないの?違いは何ですか?ソート時にユニークフラグよりuniqを使用する方が良いのはなぜですか?
答え1
sort | uniq
以前にもあり、sort -u
より広い範囲のシステムと互換性がありますが、ほとんどすべての最新システムがこれをサポートしています。-u
まさにPOSIXです。これはほとんど存在しなかった時代の後退です(人々は、既知の方法が機能し続けることがわかっている場合は、自分の方法を変える傾向がないでしょう。養子縁組と比較してみてくださいsort -u
)。ifconfig
ip
ファイルから重複エントリを削除するには、ソート(少なくとも標準ケースでは)が必要で、ソートのための非常に一般的なユースケースなので、2つはマージされる可能性が高いです。両方のタスクを同時に実行する能力のため(そしてIPCは必要ありません(プロセス間通信)間uniq
)sort
。特に、ファイルが大きい場合、照合sort -u
に使用される中間ファイルの数が少なくなる可能性があります。
私のシステムでは、次の結果が引き続き表示されます。
$ dd if=/dev/urandom of=/dev/shm/file bs=1M count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 8.95208 s, 11.7 MB/s
$ time sort -u /dev/shm/file >/dev/null
real 0m0.500s
user 0m0.767s
sys 0m0.167s
$ time sort /dev/shm/file | uniq >/dev/null
real 0m0.772s
user 0m1.137s
sys 0m0.273s
また、重要な可能性のある戻りコードをマスクしません(最新のシェルには、配列のようにsort
これを取得するためのいくつかの方法がありますが、これは常に正しいとは限りません)。bash
$PIPESTATUS
答え2
POSIX互換sort
sとuniq
sの場合(GNUはuniq
現在これに関して互換性がありません)違いがありますsort
ロケールの照合アルゴリズムを使用して、文字列(通常はstrcoll()
文字列を比較するために使用される)を比較し、バイトuniq
値識別子(一般的に使用されるstrcmp()
)を確認します。
これは少なくとも2つの理由で重要です。
一部のロケール、特にGNUシステムには、同じソートを実行するさまざまな文字があります。たとえば、GNUシステムのen_US.UTF-8ロケールではソート順序が定義されていないため、すべての①②②③④④⑤⑥⑧⑩…文字²は他の多くの文字と同じようにソートされます。 0123456789 アラビア数字の順序は次のとおりです。東アラビア語インド語相手(٠١٢٣٤٥٦٧٨٩)。
の場合
sort -u
①は②と同じで、0123は٠١٢٣と同じなので1つだけ維持されsort -u
、(uniq
GNUを使用しない(除外))の場合①は②と異なり、0123は٠١٢٣と異なるため4つすべて保持されます。一意の項目が考慮されます。uniq
strcoll()
-f
uniq
strcoll
strcmp()
バイト間比較のみを実行するため、文字に関係なく有効な文字の文字列(入力に有効な文字を形成しないバイトシーケンスがある場合はPOSIXに従って定義されていない動作)のみを比較できます。したがって、sort -u
その行の一部が有効なテキストを形成しない場合、これはすべての一意の行を提供できない可能性があるもう1つの理由です。sort|uniq
、テキスト以外の入力にはまだ指定されていませんが、実際には結果として一意の行を提供する可能性が高くなります。
これらの微妙さとは別に、これまで注目されていないことの1つは、行全体が語彙的uniq
に比較されるのに対し、sort
s-u
はコマンドラインで提供されたソート仕様に従って比較されることです。
$ printf '%s\n' 'a b' 'a c' | sort -uk 1,1
a b
$ printf '%s\n' 'a b' 'a c' | sort -k 1,1 | uniq
a b
a c
$ printf '%s\n' 0 -0 +0 00 '' | sort -n | uniq
0
-0
+0
00
$ printf '%s\n' 0 -0 +0 00 '' | sort -nu
0
1 POSIX仕様の初期バージョンでは、LC_COLLATE
変数を影響を受ける変数としてリストして混乱を引き起こしましたuniq
。これは2018年版から削除され、上記の説明に従って動作が明確になりました。バラより対応するオースティングループエラー
²2019年編集。これらの問題は解決されたが、GNU libcバージョン2.30以降、Unicodeコードポイントの95%以上がまだ定義されていない順序があります。。あなたはテストすることができます
答え3
1つの違いは、uniq
比較のためにフィールドをスキップして値の繰り返し数を計算するなど、便利な追加オプションが多いことです。sort
フラグ-u
は、変更されていないコマンドの機能のみを実装しますuniq
。
答え4
今日私が見つけたもう1つの違いは、区切り文字に基づいてソートするときに一意のsort -u
フラグがソート中の列にのみ適用されることです。
$ cat input.csv
3,World,1
1,Hello,1
2,Hello,1
$ cat input.csv | sort -t',' -k2 -u
1,Hello,1
3,World,1
$ cat input.csv | sort -t',' -k2 | uniq
1,Hello,1
2,Hello,1
3,World,1