web-dev-qa-db-ja.com

uniqはどのように機能しますか?

この質問を「b/w sort -uとsort | uniqの違い」の重複と混同しないでください。

これは本質的にワードカウントプログラムです

次のコマンドから生じる混乱が、この質問をする理由です。

    root@sanctum:~/datascience# cat data 
    this is a file that is supposed to be a file

これにより、誤った出力が得られます。

root@sanctum:~/datascience# cat data | sed 's/ /\n/g' | uniq -c
      1 this
      1 is
      1 a
      1 file
      1 that
      1 is
      1 supposed
      1 to
      1 be
      1 a
      1 file

出力を並べ替えてからuniqにパイピングすると、完璧な答えが得られます。

root@sanctum:~/datascience# cat data | sed 's/ /\n/g' | sort |uniq -c
      2 a
      1 be
      2 file
      2 is
      1 supposed
      1 that
      1 this
      1 to

ソートするためだけにパイプされたときの出力:

root@sanctum:~/datascience# cat data | sed 's/ /\n/g' | sort 
a
a
be
file
file
is
is
supposed
that
this
to

行の出現の行番号は、ファイル内の出現回数にどのように影響しますか? 私はそれを表現する方法を知らないが、あなたはポイントを得る

基本的にできない理由cat data | sed 's/ /\n/g' | uniq -c必要な結果を出しますか?

1
juggernauthk108

これはランダムな動作ではありません。 _man uniq_から:

注: 'uniq'は、隣接していない限り、繰り返される行を検出しません。最初に入力をソートするか、「uniq」なしで「sort -u」を使用することができます。また、比較は「LC_COLLATE」で指定されたルールを尊重します。

基本的に、uniqはデフォルトでsorted入力でのみ機能します。つまり、設計によるものです。

ただし、主な質問は次のとおりです。

行の出現の行番号は、ファイル内の出現回数にどのように影響しますか

この質問に答えるには、ソースコードを実際に見る必要があります。

_ while (!feof (stdin))
    {
      char *thisfield;
      size_t thislen;
      if (readlinebuffer_delim (thisline, stdin, delimiter) == 0)
        break;
      thisfield = find_field (thisline);
      thislen = thisline->length - 1 - (thisfield - thisline->buffer);
      if (prevline->length == 0
          || different (thisfield, prevfield, thislen, prevlen))
        {
          fwrite (thisline->buffer, sizeof (char),
                  thisline->length, stdout);

          SWAP_LINES (prevline, thisline);
          prevfield = thisfield;
          prevlen = thislen;
        }
    }
_

ここで重要なのは、ファイルが読み取られる行ごとであり、関数different()の現在の行と前の行でのみ比較が可能であることです。 、それらが同じ場合はFalse。その理由は、all行と比較する場合、行数が多い場合はおそらく大量のメモリが必要になるためです。これは実用的ではなく、uniqをかなり遅くします

2