powershell - 针对大分隔文件的聚合操作的 Powershell 性能调整
问题描述
我有一个包含 350 列的分隔文件。分隔符是\034(Field separator)
. 我必须提取一个特定的列值并找出文件中该列的每个不同值的计数。如果不同值的计数大于或等于 2,我需要将其输出到文件。源文件为 1GB。我写了以下命令。它非常慢。
Get-Content E:\Test\test.txt | Foreach {($_ -split '\034')[117]} | Group-Object -Property { $_ } | %{ if($_.Count -ge 2) { Select-Object -InputObject $_ -Property Name,Count} } | Export-csv -Path "E:\Test\test2.csv" -NoTypeInformation
请帮忙!
解决方案
我建议使用switch
语句来快速处理输入文件(按 PowerShell 标准):
# Get an array of all the column values of interest.
$allColValues = switch -File E:\Test\test.txt {
default { # each input line
# For better performance with *literal* separators,
# use the .Split() *method*.
# Generally, however, use of the *regex*-based -split *operator* is preferable.
$_.Split([char] 0x1c)[117] # hex 0x1c is octal 034
}
}
# Group the column values, and only output those that occur at least
# twice.
$allColValues | Group-Object -NoElement | Where-Object Count -ge 2 |
Select-Object Name, Count | Export-Csv E:\Test\test2.csv -NoTypeInformation
向Mathias R. Jessen 致敬,感谢他提出了转换的建议,该转换通过仅维护抽象组信息-NoElement
来简化呼叫;也就是说,只有分组标准(反映在 中,而不是组成组的各个对象(通常反映在 中)通过输出对象返回。Group-Object
.Name
.Group
至于你尝试了什么:
Get-Content
流水线中的逐行流式传输速度很慢,通常是(逐个对象传递引入开销),特别是因为Get-Content
使用 ETS(扩展类型系统)元数据装饰它输出的每一行。- GitHub 问题 #7537建议添加一种选择退出此装饰的方法。
- 以内存消耗和可能的行拆分额外工作为代价,开关将整个文件
-Raw
作为单个多行字符串读取,这要快得多。
没有必要传递
-Property { $_ }
给- 只需省略它。Group-Object
没有-Property
参数,输入对象被分组为一个整体。链接
Where-Object
和- 而不是通过与多个调用组合的调用中的语句进行Select-Object
过滤- 不仅在概念上更清晰,而且性能更好。if
ForEach-Object
Select-Object
推荐阅读
- oracle - 我希望这个触发器在审计表中插入数据并抛出错误。但这只会引发错误,但不会插入数据
- python - ModuleNotFoundError:Scrapy 中没有名为“”的模块
- chef-infra - 刀库刷新命令无法搜索查询
- excel - VBA - VBA 运行时无法打开工作表
- javascript - 使用 Ajax 插入和获取数据插入工作但 fetch 功能不工作
- html - 如何在悬停时将图标的颜色更改为白色
- javascript - 如何切换密码
- sequelize.js - Sequelize 配置读取错误的方言
- c - 在 C 中创建图像内核释放内存错误
- java - 如何将大文本(字符串)作为 REST 服务的响应发送到 Java 中的 REST 客户端?