Powershell 中优雅的词频
Word frequency elegantly in Powershell
Donald Knuth 曾经接到任务,编写一个计算文件词频的读写程序。
Read a file of text, determine the n most frequently used words, and print out a sorted list of those words along with their frequencies.
Doug McIlroy 用几行 sh 重写了 Pascal 的 10 页而著名:
tr -cs A-Za-z '\n' |
tr A-Z a-z |
sort |
uniq -c |
sort -rn |
sed 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
。
第一行看起来很难看,不知道能不能写得优雅一点?也许有办法以某种方式加载带有正则表达式定界符的文件?
一种明显的缩短代码的方法是使用别名,但这无助于提高可读性。
我会这样做。
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]
感谢 js2010 和 LotPings 的重要提示。记录什么可能是最好的解决方案:
$Input -split '\W+' |
Group-Object -NoElement |
Sort-Object count -Descending |
Select-Object -First $Args[0]
我学到的东西:
$Input
包含标准输入。这比 Get-Content 一些文件更接近 McIlroys 代码。
- split 实际上可以采用正则表达式定界符
-NoElement
参数让我摆脱了 Format-Table 行。
Windows 10 个 64 位。 PowerShell 5
如何找出文本文件中最常使用的单词(the
而不是 -the-
或 weathe
r)以及使用次数使用 Powershell:
将 1.txt 替换为您的文件。
$z = gc 1.txt -raw
-split $z | group -n | sort c* | select -l 1
结果:
Count Name
----- ----
30 THE
Donald Knuth 曾经接到任务,编写一个计算文件词频的读写程序。
Read a file of text, determine the n most frequently used words, and print out a sorted list of those words along with their frequencies.
Doug McIlroy 用几行 sh 重写了 Pascal 的 10 页而著名:
tr -cs A-Za-z '\n' |
tr A-Z a-z |
sort |
uniq -c |
sort -rn |
sed 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
。
第一行看起来很难看,不知道能不能写得优雅一点?也许有办法以某种方式加载带有正则表达式定界符的文件?
一种明显的缩短代码的方法是使用别名,但这无助于提高可读性。
我会这样做。
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]
感谢 js2010 和 LotPings 的重要提示。记录什么可能是最好的解决方案:
$Input -split '\W+' |
Group-Object -NoElement |
Sort-Object count -Descending |
Select-Object -First $Args[0]
我学到的东西:
$Input
包含标准输入。这比 Get-Content 一些文件更接近 McIlroys 代码。- split 实际上可以采用正则表达式定界符
-NoElement
参数让我摆脱了 Format-Table 行。
Windows 10 个 64 位。 PowerShell 5
如何找出文本文件中最常使用的单词(the
而不是 -the-
或 weathe
r)以及使用次数使用 Powershell:
将 1.txt 替换为您的文件。
$z = gc 1.txt -raw
-split $z | group -n | sort c* | select -l 1
结果:
Count Name
----- ----
30 THE