並べ替えられた一意のリストを取得する必要がある人を見ると、常に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の時点で未定義の順序があります。たとえば、新しいバージョンでは、代わりに🧙🧚🧛🧜🧝でテストできます