首页 > 解决方案 > Powershell中优雅的词频

问题描述

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.

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

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

标签: powershellknuth

解决方案


我会这样做。

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]

推荐阅读