回答:
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
配列ですが、これは常に正しいとは限りませんでした)。
sort | uniq
、10回のうち9回は実際にに配管しているからuniq -c
です。
sort -u
の1979年バージョンごろ、第7版UNIXの一部であったsort
ためにサポートしていない-u
か、POSIXのデジュール標準の前にデファクトスタンダードに注意せずに書かれた-本当に古風です。スタックオーバーフローも参照してくださいLinuxのシェルで並べ替えとuniqは 2010年から
ip
。2016年と2013年のこの投稿ですが、ip
今はコマンドについてしか知りません。
uniq -c
」(およびにもう一度配管しますsort -nr | head
)の場合は+1 。sort | uniq
Vimに:sort u
コマンドがあることを知ったとき、Vimに相当するものは何だろうと思っていました。TILもsort -u
存在します。
sort -n | uniq
vs. を使用する場合は違いがあることに注意してくださいsort -n -u
。たとえば、末尾の空白と先頭の空白はsort -n -u
、前者によってではなく重複として認識されます!echo -e 'test \n test' | sort -n -u
を返しますがtest
、echo -e 'test \n test' | sort -n | uniq
両方の行を返します。
違いの1つは、uniq
比較のためにフィールドをスキップしたり、値の繰り返し回数をカウントしたりするなど、多くの便利な追加オプションがあることです。sort
の-u
フラグは、装飾のないuniq
コマンドの機能のみを実装します。
sort -u
渡すことができませんuniq
。」
POSIXに準拠してsort
Sとuniq
S(GNUはuniq
その点では、現在対応していない)、違いがありますようにsort
(一般的に使用されます文字列を比較するために、ロケールの照合アルゴリズムを使用strcoll()
しながら、文字列を比較するために)uniq
、バイト値のアイデンティティのためのチェックが(一般的に使用されますstrcmp()
) 。
それは少なくとも2つの理由で重要です。
一部のロケール、特にGNUシステムでは、同じようにソートされるさまざまな文字があります。たとえば、GNUシステムのen_US.UTF-8ロケールでは、並べ替え順序が定義されていないため、すべての①②③④⑤⑥⑦⑧⑨⑩...文字と他の多くの文字が同じように並べ替えられます。0123456789アラビア数字は、東アラビアアラビア語の対応する数字(٠١٢٣٤٥٦٧٨٩)と同じようにソートされます。
のためにsort -u
、①は②と同じようにソートされ、0123はsameと同じなのでsort -u
、それぞれを1つだけ保持しますが、uniq
(GNU uniq
ではなくstrcoll()
(を除く-i
)を使用する)、①は②と異なり、0123は٠١٢٣と異なるため、uniq
すべてを考慮します4ユニーク。
strcoll
有効な文字列のみを比較できます(入力に有効な文字を形成しないバイトシーケンスがある場合の動作はPOSIXによって定義されていません)が、strcmp()
バイト単位の比較のみを行うため、文字は気にしません。そのためsort -u
、一部の行が有効なテキストを形成しない場合、すべての一意の行が表示されない場合があります。sort|uniq
、非テキスト入力ではまだ指定されていませんが、実際には、その理由で一意の行を提供する可能性が高くなります。これらの微妙な点のほかに、これまで指摘されていない一つのことはそれがあるuniq
一方で、辞書的に行全体を比較するsort
のは-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
大文字と小文字が混在する文字列を含む重複を削除するために(重複を削除する)オプションsort | uniq
を使用しようとすると-u
、結果を理解するのが簡単ではないため、使用することを好みます。
注:以下の例を実行する前に、以下を実行して標準C照合シーケンスをシミュレートする必要があります。
LC_ALL=C
export LC_ALL
たとえば、ファイルを並べ替えて重複を削除すると同時に、文字列の異なるケースを区別したい場合。
$ cat short #file to sort
Pear
Pear
apple
pear
Apple
$ sort short #normal sort (in normal C collating sequence)
Apple #the lower case words are at the end
Pear
Pear
apple
pear
$ sort -f short #correctly sorts ignoring the C collating order
Apple #but duplicates are still there
apple
Pear
Pear
pear
$ sort -fu short #By adding the -u option to remove duplicates it is
apple #difficult to ascertain the logic that sort uses to remove
Pear #duplicates(i.e., why did it remove pear instead of Pear?)
この混乱は-u
、重複を削除するオプションを使用しないことで解決されます。使用uniq
はより予測可能です。以下は、最初にケースをソートして無視し、次にそれを渡してuniq
重複を削除します。
$ sort -f short | uniq
Apple
apple
Pear
pear
-u
オプションは、同等の実行の最初をsort
出力します(manページを参照)。したがって、大文字と小文字を区別しないすべての一意の行の最初の出現をピックアップします。重複を削除するために使用するロジックは予測可能です。sort -fu
sort
今日見つけた別の違いは、デリミターに基づいて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