コマンドラインでテキストファイル内の単語の出現回数をカウントするにはどうすればよいですか?


43

1行に大きなJSONファイルがあり、コマンドラインを使用して、ファイル内の単語の出現回数をカウントできるようにします。どうやってやるの?


JSONデータのキーと値の両方で単語を一致させる必要があるかどうか、つまり{ "key": "the key" }、文字列をkey1回または2回カウントする必要があるかどうかは不明です。
クサラナンダ

回答:


46
$ tr ' ' '\n' < FILE | grep WORD | wc -l

trスペースを改行で置換する場合、grepWORDに一致するすべての結果の行をフィルタリングしwc、残りの行をカウントします。

grep wc-cオプションを使用してパーツを保存することもできます。

$ tr ' ' '\n' < FILE | grep -c WORD

この-cオプションはPOSIXで定義されています。

単語間にスペースがあることが保証されない場合は、他の文字を(区切り文字として)使用して置換する必要があります。たとえば、代替tr部品は

tr '"' '\n'

または

tr "'" '\n'

二重引用符または単一引用符を置き換える場合。もちろん、tr複数の文字を一度に置き換えるためにも使用できます(異なる種類の空白や句読点を考えてください)。

prefixWORD、WORDsuffix、またはprefixWORDsuffixではなくWORDをカウントする必要がある場合、WORDパターンをbegin / end-of-lineマーカーで囲むことができます。

grep -c '^WORD$'

私たちの文脈では、これは単語開始/終了マーカーと同等です:

grep -c '\<WORD\>'

スペースがない場合、つまりフィールド名が引用符で囲まれている場合はどうなりますか?例:「フィールド」
神話

@mythz:その後、引用符をtrの改行で置き換えます。答えを更新します。
maxschlepzig

1
この答えは多くの点で間違っています。あいまいですtr。すべての状況で機能することのない例を提案するのではなく、ジョブを実行するコマンドを作成する方法を説明する必要があります。また、探している単語を含む単語と一致します。grep -o '\<WORD\>' | wc -lソリューションは、はるかに優れています。
サムホセバー

1
@Sam、検索された単語を 'WORD'または '\ <WORD \>'のように検索する必要がある場合、質問は開いたままにします-両方の方法で読むことができます。たとえ2番目の方法でしか読んでいないとしても、私の答えは1つの方法でのみ間違っています。;)そして、 'grep -o'ソリューションは、POSIXで指定されていない-oオプションをサポートしている場合にのみ優れています。漠然とした
...-maxschlepzig

1
@Kusalananda、まあ、それはまだ発生しています。しかし、そのような部分文字列の一致をカウントしたくない場合は、ここで私の答えの最後の段落と以前のコメントを読んでください。
maxschlepzig

24

GNU grepを使用すると、これは機能します。 grep -o '\<WORD\>' | wc -l

-o 各行の一致した各部分を別々の行に出力します。

\<単語の始まりを表明し\>、単語の終わりを\b表明します(Perlの場合と同様)。これにより、単語の途中の文字列と一致しないことが保証されます。

例えば、

$ python -c 'これをインポート' | grep '\ <one \>'
あるべき1、好ましくのみ- 1それを行うには--obvious方法。
名前空間は素晴らしいアイデアの1つです。それらをもっとやってみましょう。
$ python -c 'これをインポート' | grep -o '\ <one \>'
 one 
one 
one 
$ python -c 'import this' | grep -o '\ <one \>' | wc -l
3

1
またはちょうどgrep -wo WORD | wc -l
ステファンシャゼル

10

残念ながら、これ GNU では機能しませんcoreutils

grep -o -c WORD file

プラットフォームで動作する場合、エレガントでかなり直感的なソリューションです。しかし、GNUの人々はまだ考えています。


2
私の悪い、バグはまだ開いています:savannah.gnu.org/bugs/
33080

1
残念これは最もエレガントされているだろう
MasterScrat

これは私のために働いた!
ThisaruG

これは間違っています。これにより、パターンWORDの行数がカウントされます。OPは、オカレンスの総数を求めています。
ピエールB

@PierreBだからこそgrep、GNU にはバグがあると言っています。結合のセマンティクスがPOSIXから明確-c-oはないため、これは現在移植性がありません。コメントありがとうございます。この回答を更新しました。
トリプリー

7
sed -e 's/[^[:alpha:]]/ /g' text_to_analize.txt | tr '\n' " " |  tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl 

このコマンドは次のことを行います。

  1. すべての非英数字を空白で置き換えます。
  2. すべての改行もスペースに変換されます。
  3. すべての複数の空白スペースを1つの空白スペースに減らします
  4. すべてのスペースが改行に変換されるようになりました。行の各単語。
  5. すべての単語を小文字に変換して、「Hello」と「hello」が異なる単語になるのを防ぎます
  6. テキストを並べ替えます
  7. 等しい行をカウントして削除する
  8. 最も頻度の高い単語を数えるために逆順に並べ替えます
  9. 単語の位置を全体的に把握するために、各単語に行番号を追加します

たとえば、最初のLinus Torvaldメッセージを分析する場合:

From:torvalds@klaava.Helsinki.FI(Linus Benedict Torvalds)ニュースグループ:comp.os.minix件名:minixで最も見たいものは何ですか?要約:新しいオペレーティングシステムの小規模な調査メッセージID:<1991Aug25.205708.9541@klaava.Helsinki.FI>日付:25 Aug 91 20:57:08 GMT組織:ヘルシンキ大学

みなさんこんにちはminixを使用して–

私は386(486)ATクローン用の(無料の)オペレーティングシステム(趣味であり、gnuのように大きくて専門的ではありません)を行っています。これは4月から醸造されており、準備を始めています。私のOSは多少似ているので、minixで人々が好き/嫌いなものについてのフィードバックが欲しいです(他のものの間でファイルシステムの物理的なレイアウト(実際的な理由のため)と同じです)。

現在bash(1.08)とgcc(1.40)を移植しましたが、うまくいくようです。これは、数か月以内に何か実用的なものを手に入れることを意味し、ほとんどの人がどんな機能を望んでいるかを知りたいと思います。どんな提案も歓迎しますが、私はそれらを実装することを約束しません🙂

Linus(torvalds@kruuna.helsinki.fi)

PS。はい。minixコードは一切なく、マルチスレッドfsがあります。protableではなく(386タスクの切り替えなどを使用)、ATハードディスク以外はサポートしません。

linus.txtという名前のファイルを作成し、コンテンツを貼り付けて、コンソールに書き込みます。

sed -e 's/[^[:alpha:]]/ /g' linus.txt | tr '\n' " " |  tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl 

出力は次のようになります。

 1        7 i
 2        5 to
 3        5 like
 4        5 it
 5        5 and
 6        4 minix
 7        4 a
 8        3 torvalds
 9        3 of
10        3 helsinki
11        3 fi
12        3 any
13        2 would
14        2 won
15        2 what
16        ...

最初の20単語のみを視覚化する場合:

sed -e 's/[^[:alpha:]]/ /g' text_to_analize.txt | tr '\n' " " |  tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl | head -n 20

コマンドtr 'AZ' 'a-z'まだ UTF-8をサポートしていないため、外国語ではAPR soSという単語がaprÈsに翻訳されることに注意することが重要です。

1つの単語の出現のみを検索する場合は、最後にgrepを追加できます。

sed -e 's/[^[:alpha:]]/ /g' text_to_analize.txt | tr '\n' " " |  tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl | grep "\sword_to_search_for$"

search_freqというスクリプトで:

#!/bin/bash
sed -e 's/[^[:alpha:]]/ /g' text_to_analize.txt | tr '\n' " " |  tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl | grep "\s$1$"

スクリプトを呼び出す必要があります。

 search_freq word_to_search_for

sed: -e expression #2, char 7: unterminated 「コマンド」、これもすべての単語をカウントしますよね?しかし、OPは特定のもののみを尋ねました。また、ちょっとした説明もいいでしょう。
phk 16

すみません、間違えました。私はコマンドを作り直し、答えにコメントしました。私の意見では、質問から、彼がたった1つの単語の出現頻度または出現頻度を取得したいかどうかを知ることは不可能です。ただし、単語を1つだけ取得したい場合は、最後にgrepを追加できます。
ロジャーボレル

3

JSONデータのキーまたは値の単語を一致させるかどうかに応じて、データからキーのみまたは値のみを抽出することができます。そうしないと、キーと値の両方として出現する単語が何度もカウントされる可能性があります。

すべてのキーを抽出するには:

jq -r '..|objects|keys[]' <file.json

これは、現在のものがオブジェクトであるかどうかを再帰的にテストし、オブジェクトである場合、キーを抽出します。出力は、1行に1つずつ、キーのリストになります。

すべての値を抽出するには:

jq -r '..|scalars' <file.json

これは同様の方法で機能しますが、手順は少なくなります。

次に、上記の出力をgrep -c 'PATTERN'(キーまたは値に対してパターンgrep -c -w -F 'WORD'を一致させるために)、または(キーまたは値内の単語を一致させるために)、または(キーまたは値全体grep -c -x -F 'WORD'に一致させるために)または同様のものを介してパイプすることができますあなたのカウントを行います。


0

私はこのようなものでjsonを持っています:"number":"OK","number":OK"1行で複数回繰り返されます。

私の簡単な「OK」カウンター:

sed "s|,|\n|g" response | grep -c OK


-1

i以下のawkコマンドを使用して、出現回数を見つけました

サンプルファイル

猫のファイル1

praveen ajay 
praveen
ajay monkey praveen
praveen boy praveen

コマンド:

awk '{print gsub("praveen",$0)}' file1 | awk 'BEGIN{sum=0}{sum=sum+$1}END{print sum}'

出力

awk '{print gsub("praveen",$0)}' file1 | awk 'BEGIN{sum=0}{sum=sum+$1}END{print sum}'

5

または単にawk '{sum+=gsub("praveen","")} END {print sum+0}'
G-Manによると、「Reinstate Monica」

なぜ私の答えに反対票を投じるのか教えてください
Praveen Kumar BS
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.