ファイル内のすべての単語の数を数えるコマンドを探しています。たとえば、ファイルが次のような場合、
today is a
good day
5
そこに5
単語があるので、印刷する必要があります。
ファイル内のすべての単語の数を数えるコマンドを探しています。たとえば、ファイルが次のような場合、
today is a
good day
5
そこに5
単語があるので、印刷する必要があります。
回答:
コマンドwc
別名。ワードカウントで実行できます。
$ wc -w <file>
$ cat sample.txt
today is a
good day
$ wc -w sample.txt
5 sample.txt
# just the number (thanks to Stephane Chazelas' comment)
$ wc -w < sample.txt
5
wc -w
定義はGNUと同じではないことに注意してくださいgrep -w
。以下のためにwc
単語一つ以上の非空白文字(のシーケンスである[:space:]
現在のロケールの文字クラス)。たとえば、foo,bar
and foo bar
(改行なしスペースを含む)はそれぞれ1ワードです。
私はこれだけで番号を思いついた:
wc -w [file] | cut -d' ' -f1
5
私もwc -w < [file]
アプローチが好きです
最後に、単語カウントのみを変数に格納するには、次を使用できます。
myVar=($(wc -w /path/to/file))
これにより、ファイル名をエレガントにスキップできます。
wc -w < "$file"
ちょうど数。
より良い解決策は、Perlを使用することです。
perl -nle '$word += scalar(split(/\s+/, $_)); END{print $word}' filename
@ベルンハルト
wc
coreutilsからコマンドのソースコードを確認できます。bash4.2 subst.c
ソースのファイルを使用して、マシンでテストします。
time wc -w subst.c
real 0m0.025s
user 0m0.016s
sys 0m0.000s
そして
time perl -nle '$word += scalar(split(" ", $_)); END{print $word}' subst.c
real 0m0.021s
user 0m0.016s
sys 0m0.004s
ファイルが大きいほど、Perlはに関してより効率的wc
です。
wc
Perlで約5秒かかったのに最大14秒かかりました。
split
に/\s+/
似split(' ')
ていることに注意してください。ただし、先頭の空白はnullの最初のフィールドを生成します。この違いにより、行リンクごとに1つの余分な単語(つまり、null最初のフィールド)が与えられます。その(split(" ", $_))
ため、このように作成されたファイルには別の方法で使用しecho -e "unix\n linux" > testfile
ます。ワンライナーは3ワードを報告します。
wc
するとPERLIO=:utf8
、perl
と同様に大幅に高速になり、大幅に遅くなります。
$ function wordfrequency() { awk 'BEGIN { FS="[^a-zA-Z]+" } { for (i=1; i<=NF; i++) { word = tolower($i) words[word]++ } } END { for (w in words) printf("%3d %s\n", words[w], w) } ' | sort -rn }
$ cat your_file.txt | wordfrequency
これは、提供されたファイルで発生する各単語の頻度をリストします。私はそれがあなたが求めたものではないことを知っていますが、より良いです!単語の出現を確認したい場合は、次のようにします。
$ cat your_file.txt | wordfrequency | grep yourword
この関数を.dotfilesに追加しました
wc
このプログラムは、「言葉」を数えますが、それらは、彼らがファイルを調べたときに多くの人が見るであろうことを、たとえば「言葉」ではありません。vi
一方、インスタンスのためのプログラムは、その文字クラスに基づいて、それらを区切る「言葉」の異なる指標を、使用してwc
簡単に物事がカウント空白で区切られました。2つのメジャーは根本的に異なる場合があります。この例を考えてみましょう:
first,second
vi
見て3つのワード(第一及び第二しばらくは、だけでなく、それらを分離するコンマ)wc
見ているものを(その行には空白がありません)。単語を数える方法はたくさんありますが、他の方法よりも有用性が低いものもあります。
Perlはより良いのvi風の言葉のためにカウンターを書くことに適しているだろうが、ここで使用した簡単な例であるsed
、tr
およびwc
(リテラルキャリッジリターンを使用して適度にポータブル^M
):
#!/bin/sh
in_words="[[:alnum:]_]"
in_punct="[][{}\\|:\"';<>,./?\`~!@#$%^&*()+=-]"
sed -e "s/\($in_words\)\($in_punct\)/\1^M\2/g" \
-e "s/\($in_punct\)\($in_words\)/\1^M\2/g" \
-e "s/[[:space:]]/^M/g" \
"$@" |
tr '\r' '\n' |
sed -e '/^$/d' |
wc -l
カウントの比較:
wc
すると28が得られます。参考のために、POSIX viは次のように述べています。
POSIXロケールでは、viは5種類の単語を認識します。
両端が次のように区切られた、文字、数字、アンダースコアの最大シーケンス。
文字、数字、またはアンダースコア以外の文字
行の始まりまたは終わり
編集バッファーの開始または終了
文字、数字、アンダースコア、または文字以外の文字の最大シーケンスで、両端が次のように区切られています。
- 文字、数字、アンダースコア
<blank>
キャラクター- 行の始まりまたは終わり
- 編集バッファーの開始または終了
1つ以上の連続した空白行
編集バッファーの最初の文字
<newline>
編集バッファー内の最後の非
wc -w $FILE
か?