awkは、連続した2つの単語の最も一般的なシーケンスを探します。

awkは、連続した2つの単語の最も一般的なシーケンスを探します。

「ファイル」というテキストファイルがあります。 「this is」と「is this」が等しいと見なされる最も一般的な2つの単語シーケンスを見つけるには、awkを使用する必要があります。

テキスト例:私の名前はで、これは次のテキストです。

期待される出力: 3 か。

私はこのループを使用しました:

awk 'BEGIN{
    for(i=1;i<NF;i++) 
    a[$i OFS $(i+1)]++
    }' file

なぜこれが失敗するのか知っている人はいますか?

答え1

ファイルを読み取らないため、コードは失敗します。特殊BEGINブロックが実行されます。今後コマンドラインに名前が付けられた最初の入力ファイルも読み取り用に開きます(END最後のファイルの次のブロックも同じです)。また、コードの出力はありません。

他のユーザーはすでに独自のソリューションを提供しているので、コードをインポートして少し修正します。

  1. 入力の各行に対して実行されるように、通常のブロックでコードを実行します。
  2. ブロックを使用してEND配列内で最も一般的な単語の組み合わせを見つけ、すべての入力が処理された後に出力します。
  3. 各ペアの単語が常にアルファベット順に使用されていることを確認してください。
awk '
    {
        for (i = 1; i < NF; i++)
            if ($i < $(i+1)) a[$i OFS $(i+1)]++
            else             a[$(i+1) OFS $i]++
    }
    END {
        for (words in a)
            if (a[words] > a[m]) m = words
        print m, a[m]
    }' file

与えられた入力に従って印刷されますis this 3

別の実装は、ファイルの読み取り中に最大値を追跡し、最後に印刷することです。

awk '
    {
        for (i = 1; i < NF; ++i) {
            if ($i < $(i+1)) words = $i OFS $(i+1)
            else             words = $(i+1) OFS $i
            if (++count[words] > count[m]) m = words
        }
    }
    END { print m, count[m] }' file

配列について心配しないでください。

awk '{ for (i = 1; i < NF; ++i) if ($i < $(i+1)) print $i, $(i+1); else print $(i+1), $i }' file | sort | uniq -c | sort -n | tail -n 1

つまり、awk単語の組み合わせを生成(1行に1つずつ)を使用してソートし、それぞれの発生回数を取得してソートします。これら(数に基づいて)最も高い数を選択してください。大きなデータを呼び出してsort電子メールなどの小さなデータを実行するのは高価ですが、十分です。

答え2

努力する:

gawk '{
       for (i=2; i<=NF; i++) {
           delete arr; split($(i-1) "\n" $i, arr);
           asort(arr); s[arr[1] FS arr[2]]++
       };
     }
END { for(x in s) print s[x], x }' infile |sort -nr
3 is this
2 my name
1 our text
1 is text
1 is our
1 is name

split()この関数は、スペース(タブ/スペース)で区切られた文字列のペアを配列に追加しますarrが、各文字列は別々の行にあります\n

asort()関数はarrその配列をソートします。次に、ソートされた文字列ペアとしてキーを使用して呼び出される別の配列に結果を追加しs、再度発生すると、同じ文字列ペアごとに値が増加します。

delete arrarr次のフィールドペアを処理するために配列を削除します。

END配列要素を繰り返しs、ペア自体とともに表示される各要素ペアの数を印刷した後、結果がソートされ、最もsort -nr繰り返される文字列ペアが得られます。

is this注:結果はほとんどまたは全体があるかどうかを知らせず、それらのうちの1つのみを示し、この例の結果はすべてのソートさthis isれた結果のみを示します。is this

答え3

@kusalanandaが指摘したように、最大​​の間違いはすべてのコードをBEGINブロックに入れることです。したがって、"this is" and "is this" are considered equal in our count.入力に表示される相対的な順序に関係なく、出会うすべての単語のペアが特定の(並べ替えられた)順序で保存されるようにするには、次の作業を実行する必要があります。

awk '
{
    for(i=1; i<NF; i++) {
        pair = ($i > $(i+1) ? $i OFS $(i+1) : $(i+1) OFS $i)
        c = ++cnt[pair]
        max = (max > c ? max : c)
    }
}
END {
    for (pair in cnt) {
        c = cnt[pair]
        if ( c == max ) {
            print pair, c
        }
    }
}
' file
this is 3

関連情報