“ sort -u ”と“ sort |の違いは何ですか? uniq ”?

並べ替えられた一意のリストを取得する必要がある人を見ると、常にsort | uniqにパイプされます。誰かが代わりにsort -uを使用する例を見たことがありません。なぜですか?違いは何ですか?一意のフラグよりもuniqを使用して並べ替える方がよいのはなぜですか?

コメント

回答

sort | uniqはであり、より広範囲のシステムと互換性がありますが、ほとんどすべての最新システムは-uをサポートしています。これはPOSIXです。ほとんどの場合、先祖返りです。 sort -uが存在しなかった時代まで(そして、人々が知っている方法が引き続き機能する場合、人々はメソッドを変更する傾向がありません。とipの採用)。

ファイル内の重複を削除するには並べ替えが必要なため、2つはマージされた可能性があります(少なくとも標準ではケース)、そしてある種の非常に一般的なユースケースです。また、両方の操作を同時に実行できるため、内部的にも高速になります(また、uniqsort)。特にファイルが大きい場合、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に相当するものは何かと思っていました。また、TIL sort -uも存在します。
  • sort -n | uniq

。たとえば、末尾と先頭の空白はsort -n -uによって重複として表示されますが、前者によっては表示されません。 echo -e 'test \n test' | sort -n -utestを返しますが、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つだけを保持しますが、uniqstrcoll()を使用するGNU uniqではありません(-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の時点で未定義の順序があります。たとえば、新しいバージョンでは、代わりに🧙🧚🧛🧜🧝でテストできます

回答

使用したい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が重複を削除するために使用するロジックは予測可能です。

回答

今日私が見つけたもう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 

コメント

  • これは、St é faneChazelasからの回答に記載されていますが私はあなたの例が好きなので+1
  • @roaimaを指摘してくれてありがとう、その答えでは'あまり明確ではありませんでした

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です