我正在寻找一个命令来计算文件中所有单词的数量。例如,如果文件是这样的,
today is a
good day
然后应该打印5
,因为那里有5
文字。
我正在寻找一个命令来计算文件中所有单词的数量。例如,如果文件是这样的,
today is a
good day
然后应该打印5
,因为那里有5
文字。
Answers:
命令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
和foo bar
(与非打破空间)是每一个字。
我想出这个只是数字:
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中检查命令的源代码,并subst.c
在bash 4.2源文件中进行检查。
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
花了〜14秒,而Perl花了〜5秒!
split
上/\s+/
就像是一个split(' ')
不同之处在于任何前导空格产生空第一个字段。这种差异将为您每个线路 链接增加一个单词(第一个字段为空)。因此,(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中
资料来源:AWK-ward Ruby
该wc
程序会计算“单词”,但是例如,这些单词并不是许多人检查文件时会看到的“单词”。vi
例如,该程序使用不同的“单词”量度,根据它们的字符类对它们进行定界,同时wc
仅计算由空格分隔的内容。两种措施可能根本不同。考虑以下示例:
first,second
vi
看到三个单词(第一个和第二个,以及用逗号隔开),而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将识别五种单词:
字母,数字和下划线的最大序列,两端用以下字符分隔:
字母,数字或下划线以外的字符
行的开头或结尾
编辑缓冲区的开始或结束
除字母,数字,下划线或字符外的最大字符序列,两端用以下字符分隔:
- 字母,数字,下划线
<blank>
人物- 行的开头或结尾
- 编辑缓冲区的开始或结束
一或多个连续的空白行
编辑缓冲区中的第一个字符
<newline>
编辑缓冲区中的最后一个非
wc -w $FILE
吗?