it-swarm.cn

如何使用命令行计算单词在文本文件中出现的次数?

我在一行上有一个大的JSON文件,我想使用命令行来计算文件中Word出现的次数。我怎样才能做到这一点?

45
mythz
$ tr ' ' '\n' < FILE | grep Word | wc -l

tr用换行符替换空格,grep过滤所有与Word匹配的结果行​​,而wc则计算其余行。

甚至可以使用grep的-c选项保存wc部分:

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

-c选项由POSIX定义。

如果不能保证单词之间有空格,则必须使用其他字符(作为分隔符)来替换。例如,替代tr部分是

tr '"' '\n'

要么

tr "'" '\n'

如果要替换双引号或单引号。当然,您也可以使用tr一次替换多个字符(请考虑不同种类的空格和标点符号)。

如果您需要计算Word而不计算前缀WORD,WORD后缀或前缀WORD后缀,则可以将Word模式包含在行首/行尾标记中:

grep -c '^Word$'

在我们的上下文中,这等效于Word开头/结尾标记:

grep -c '\<Word\>'
48
maxschlepzig

使用GNU grep,这可以正常工作:grep -o '\<Word\>' | wc -l

-o在单独的行上打印每行的每个匹配部分。

\<断言Word的开头,而\>断言Word的结尾(类似于Perl的\b),这样可以确保您不匹配Word中间的字符串。

例如,

$ python -c'import this'| grep'\ <one \>'
应该有 -并且最好仅  -显而易见的方法。
命名空间是  敬畏的好主意-让我们做更多吧!
$ python -c'import this'| grep -o'\ <one \>'
$ python -c'import this'| grep -o'\ <one \>'| wc -l 
 3 
25
ephemient

不幸的是,这在GNU coreutils)下不起作用

grep -o -c Word file

如果它可以在您的平台上运行,那将是一个优雅而直观的解决方案。但是 GNU人们还在思考。

11
tripleee
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. 将所有多个空格减少为一个空格
  4. 现在,所有空格都将转换为换行符。一行中的每个单词。
  5. 将所有单词翻译成小写,以避免“ Hello”和“ Hello”成为不同的单词
  6. 排序文本
  7. 计算并删除相等的行
  8. 倒序排序以计算最常用的单词
  9. 为每个单词添加一个行号,以便整体了解单词位置

例如,如果我想分析第一条Linus Torvald消息:

寄件人:[email protected](Linus Benedict Torvalds)新闻组:comp.os.minix主题:minix您最想看到什么?摘要:我的新操作系统的小型民意调查Message-ID:<[email protected]>日期:91 Aug 8 20:57:08 GMT组织:赫尔辛基大学

大家好,您都在使用minix –

我正在为386(486)AT个克隆做一个(免费的)操作系统(只是一个业余爱好,不会像gnu这样大而专业)。自4月以来一直在酝酿之中,并且已经开始准备。我希望得到人们对minix中喜欢/不喜欢的事物的任何反馈,因为我的操作系统在某种程度上类似于它(文件系统的物理布局(由于实际原因))。

我目前已经移植了bash(1.08)和gcc(1.40),并且一切似乎正常。这意味着我将在几个月内得到一些实用的信息,并且我想知道大多数人想要的功能。欢迎任何建议,但我不能保证会实施它们吗?

莱纳斯([email protected]

PS。是的-它没有任何底层代码,并且具有多线程fs。它不是很稳定(使用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ÈS将被翻译为aprÈs。

如果只想搜索一个Word的出现,则可以在末尾添加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
7
Roger Borrell

根据您是想匹配键中还是JSON数据值中的Word,您可能只想从数据中提取键或仅值。否则,如果某些单词同时作为键和值出现,那么您可能会数很多次单词。

要提取所有密钥:

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

这将递归测试当前事物是否是对象,如果存在,它将提取键。输出将是键列表,每行一个。

要提取所有值:

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

这以相似的方式工作,但是步骤较少。

然后,您可以通过grep -c 'PATTERN'(以将某些模式与键或值进行匹配)或grep -c -w -F 'Word'(以将键或值中的Word匹配)传递上述内容的输出)或grep -c -x -F 'Word'(以匹配完整的键或值)或类似内容进行计数。

3
Kusalananda

我有这样的json:"number":"OK","number":OK"在一行中重复多次。

我简单的“确定”计数器:

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

0
khazad-dum_miner

使用grep -c您将只计算行数,其中一行可能会多次出现Word。

这样做:

grep -o Word foo|wc -l
0
Ramiro Velazquez