並べ替えられた一意のリストを取得する必要がある人を見ると、常にsort | uniq
にパイプされます。誰かが代わりにsort -u
を使用する例を見たことがありません。なぜですか?違いは何ですか?一意のフラグよりもuniqを使用して並べ替える方がよいのはなぜですか?
コメント
- aplawrence.com/Unixart/sort-vs-uniq.html
回答
sort | uniq
はであり、より広範囲のシステムと互換性がありますが、ほとんどすべての最新システムは-u
をサポートしています。これはPOSIXです。ほとんどの場合、先祖返りです。 sort -u
が存在しなかった時代まで(そして、人々が知っている方法が引き続き機能する場合、人々はメソッドを変更する傾向がありません。とip
の採用)。
ファイル内の重複を削除するには並べ替えが必要なため、2つはマージされた可能性があります(少なくとも標準ではケース)、そしてある種の非常に一般的なユースケースです。また、両方の操作を同時に実行できるため、内部的にも高速になります(また、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
配列ですが、これはそうではありませんでした。
コメント
- 10回のうち9回なので、
sort | uniq
を使用する傾向があります。私は'実際にuniq -c
にパイプしています。 -
sort -u
は1979年頃の第7版UNIXの一部でした。sort
のバージョンはありません-u
のサポートは本当に古風です。または、POSIX 'のデジュリスタンダードの前に事実上の標準に注意を払わずに作成されました。スタックオーバーフロー 2010年のLinuxシェルでの& uniqの並べ替えもご覧ください。 - +1
ip
の。 ' 2016年と2013年のこの投稿ですが、今はip
コマンドについてしか知りません。 - +1 " 9タイムアウト10I ' mは実際に
uniq -c
"(そしておそらくもう一度sort -nr | head
にパイプします)。 Vimに:sort u
コマンドがあることがわかったとき、Vimのsort | uniq
に相当するものは何かと思っていました。また、TILsort -u
も存在します。 -
sort -n | uniq
と
。たとえば、末尾と先頭の空白は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
コマンドの機能のみを実装します。
コメント
- +0.49は有用な答えですが、"の出力のように言います。
sort -u
を'に渡してuniq
に渡して後者の一部を使用することはできません'比較のためにフィールドをスキップしたり、繰り返し回数をカウントしたりするなどの便利なオプション。" - +1でオフセット" 'は、sort " 質問に答えますか …
回答
POSIX準拠のsort
およびuniq
(GNU uniq
は現在、その点で準拠していません)、違いがありますそのsort
は、ロケールの照合アルゴリズムを使用して文字列を比較します(通常、strcoll()
を使用して文字列を比較します)。 div id = “7787430faf”>
はバイト値のIDをチェックします(通常はstrcmp()
を使用します)¹。
これは少なくとも2つの理由で重要です。 。
-
一部のロケール、特にGNUシステムでは、同じようにソートするさまざまな文字があります。たとえば、GNUシステムのen_US.UTF-8ロケールでは、並べ替え順序が定義されていないため、すべての①②③④⑤รすこと⑧⑨⑩…文字²と他の多くの文字²が同じように並べ替えられます。 0123456789アラビア語の数字は、東部アラビア語インド語の対応する文字(٠١٢٣٤٥٦٧٨٩)と同じように並べ替えられます。
sort -u
、①は②と同じようにソートされ、0123は٠١٢٣と同じようにソートされるため、sort -u
はそれぞれ1つだけを保持しますが、uniq
(strcoll()
を使用するGNUuniq
ではありません(-i
を除く))、①は異なります②と0123は٠١٢٣とは異なるため、uniq
は4つすべてを一意と見なします。 -
strcoll
は有効な文字の文字列のみを比較できます(入力に有効な文字を形成しないバイトのシーケンスがある場合の動作はPOSIXに従って定義されていません)が、strcmp()
は気にしませんバイト間の比較のみを行うため、文字について。そのため、sort -u
の一部が有効なテキストを形成しない場合、すべての一意の行が表示されない可能性があるもう1つの理由です。sort|uniq
は、テキスト以外の入力ではまだ指定されていませんが、実際には、そのために一意の行が表示される可能性が高くなります。
これらの微妙な点に加えて、これまで注目されていないことの1つは、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
¹ POSIX仕様の以前のバージョンは混乱を引き起こしていましたが、LC_COLLATE
変数をuniq
に影響を与えるものとしてリストすることにより、2018年版で削除されました。上記の議論に続いて、動作が明確になりました。 対応するオースティングループのバグ
² 2019を参照してくださいを編集します。これらはその後修正されましたが、の95%以上のUnicodeコードポイントには、GNUlibcのバージョン2.30の時点で未定義の順序があります。たとえば、新しいバージョンでは、代わりに🧙🧚🧛🧜🧝でテストできます