コマンドラインを使用して一意の単語数を印刷します。

コマンドラインを使用して一意の単語数を印刷します。

宿題があります:

ファイルアリスにいくつかのユニークな単語があるか、そしてその数を調べてください。ソートされた一意の単語をalice_uniqueというファイルに印刷します。アポストロフィを使用して単語を分割すると、他の特殊文字と同様に正しく分割されます。

これまで私はこれを持っています

tr -sc 'A-Za-z' '\012' < alice | sort | uniq -c > alice_unique

ところで、特殊文字('、!、?など)を含む単語をどのように組み合わせるべきかわかりません。または、一意の単語の総数を計算する方法です。

テキストファイルAlice(スタート)

奇妙な国のアリス

ルイス・キャロル

ミレニアムパルクラムバージョン3.0

第1章 ウサギの洞窟に陥る

アリスはやることなく、ビーチにいる妹の隣に座っていることにうんざりし始めました。彼女は妹が読んでいる本を1、2回すすめましたが、その中には絵や会話がありませんでした。アリスは「これは何ですか?」と思いました。本ですよ、絵もなく会話もありませんか?」

それで彼女はデイジーチェーンを作る楽しさが起きてデイジーを拾う手間をするほど価値があるか一人で考えていました(暑い天気のために眠すぎて愚かだと感じたからです)。ピンクの目を持つウサギが彼女を通り過ぎています。

答え1

<alice tr -cd "[:alpha:][:space:]-'" |
  tr ' [:upper:]' '\n[:lower:]' |
  tr -s '\n' |
  sed "s/^['-]*//;s/['-]$//" |
  sort |
  uniq -c > alice_unique

一行ずつ:

  • 文字、スペース、アポストロフィ、ハイフンを除くすべての項目を削除します。
  • スペースを改行して大文字を小文字に変換
  • 連続した改行を「圧着」
  • 前または後のアポストロフィとハイフン除去
  • 単語の並べ替え
  • 各固有単語とその単語が表示される回数を表示します。

数字を単語として計算する必要がある場合、これは間違っています。テキストがASCIIでない場合は機能しない可能性があります。 ~のため奇妙な国のアリスおそらくこれで十分でしょう。

答え2

これを試してみてください。テキストファイルはどこにありますか?

awk -- '{for (i = 1; i <= NF; i++) wc[$i] += 1}; END {for (w in wc) print w, wc[w]}' <file> | sort

デフォルトでは、awkは入力フィールドの数を提供する$ 1、$ 2、...から最大NFまでのフィールドを生成し、入力の各行をスペースに分割します。また、すべての入力行を暗黙的に繰り返します。 ENDタグは、すべての行が処理された後に実行されるコードブロックを提供します。変数は宣言されず、角かっこは連想配列を参照するために使用されます。

awkプログラムは各行の各単語を取り、その単語をwc []のインデックスとして使用し、数を追加します(未定義の場合は0として扱われます)。したがって、forループとすべての行の暗黙的な外部ループはすべての一意の単語を計算します(句読点のために別の単語として計算されますが、必要に応じて簡単に修正できます)。その後、ENDブロックはすべての単語とその数を印刷します。

私はawkプログラムを複雑にするのではなく、パイプソートを使用して単語を順番に配置します。各行は一意であるため、以前の「-u」も削除しました。

答え3

以下はAWKのソリューションです。これは基本的な回避策なので、拡張が必要な​​場合があります。たとえば、聖書を分析する場合は、単語から句を除外する必要があります。

{
    if (NR == 1) { 
        sub(/^\xef\xbb\xbf/,"")
    }

    gsub(/[,;!()*:?.]*/, "")
    
    for (i = 1; i <= NF; i++) {

        w = $i
        words[w]++
    }
} 

END {

    print length(words)
}

プログラムはBOM文字を削除します。それ以外の場合、単語は「固有」になります。いくつかのデフォルトの句読点を削除します。 forループはすべてのフィールドの数を計算します。

最後に、配列の長さを取得します。

関連情報