2

Donald Knuth 曾经接到过编写一个计算文件词频的识字程序的任务。

阅读一个文本文件,确定 n 个最常用的单词,并打印出这些单词的排序列表及其频率。

著名的道格麦克罗伊用几行 sh 重写了帕斯卡的 10 页:

tr -cs A-Za-z '\n' |
tr A-Z a-z |
sort |
uniq -c |
sort -rn |
sed ${1}q

作为一个小练习,我将其转换为 Powershell:

(-split ((Get-Content -Raw test.txt).ToLower() -replace '[^a-zA-Z]',' ')) |
  Group-Object |
  Sort-Object -Property count -Descending |
  Select-Object -First $Args[0] |
  Format-Table count, name

我喜欢 Powershell 组合sort | uniq -c成一个Group-Object.

第一行看起来很丑,不知道能不能写得更优雅一点?也许有一种方法可以以某种方式使用正则表达式分隔符加载文件?

缩短代码的一种明显方法是使用别名,但这无助于可读性。

4

3 回答 3

2

我会这样做。

PS C:\users\me> Get-Content words.txt
One one
two
two
three,three.
two;two


PS C:\users\me> (Get-Content words.txt) -Split '\W' | Group-Object

Count Name                      Group
----- ----                      -----
    2 One                       {One, one}
    4 two                       {two, two, two, two}
    2 three                     {three, three}
    1                           {}

编辑:Bruce Payette 的 Windows Powershell in Action 中的一些代码

# top 10 most frequent words, hash table
$s = gc songlist.txt
$s = [string]::join(" ", $s)
$words = $s.Split(" `t", [stringsplitoptions]::RemoveEmptyEntries)
$uniq = $words | sort -Unique
$words | % {$h=@{}} {$h[$_] += 1}
$frequency = $h.keys | sort {$h[$_]}
-1..-10 | %{ $frequency[$_]+" "+$h[$frequency[$_]]}

# or
$grouped = $words | group | sort count
$grouped[-1..-10]
于 2019-05-30T13:56:28.627 回答
1

感谢 js2010 和 LotPings 的重要提示。要记录什么可能是最好的解决方案:

$Input -split '\W+' |
  Group-Object -NoElement |
  Sort-Object count -Descending |
  Select-Object -First $Args[0]

我学到的东西:

  • $Input包含标准输入。这比 Get-Content some file 更接近 McIlroys 代码。
  • split 实际上可以采用正则表达式分隔符
  • -NoElement参数让我摆脱了 Format-Table 行。
于 2019-05-30T19:01:20.283 回答
0

Windows 10 64 位。PowerShell 5

如何在文本文件中最常使用文本文件中最常使用的单词(the不区分大小写)以及使用 Powershell 使用的次数-the-the

将 1.txt 替换为您的文件。

$z = gc 1.txt -raw
-split $z | group -n | sort c* | select -l 1

结果:

Count Name
----- ----
30    THE
于 2020-05-07T01:49:08.293 回答