powershell - Powershell 在单个管道中更新多个 CSV 列值
问题描述
我正在处理 CSV 中的“修复”数据并使用 PowerShell,因为行数超出了 Excel 的喜好,而且我通常在一个文件夹中也有多个 CSV,我需要对其进行相同的更新。我很难找到一种简洁的方法来检查各个列的数据,然后根据需要进行更新。我可以使用多个管道/命令来完成它,但我想一次完成所有操作,而且我也对做类似的事情持谨慎态度,$csvData = Import-CSV...
因为有很多行。
下面是我开始使用的 3 个命令,关于如何一次运行它们的任何想法?
Import-CSV $Filepath | %{if([string]::IsNullOrEmpty($_."Type of Admission")){$_."Type of Admission" = "9"} ; $_} | Export-CSV $NewFilepath -UseQuotes AsNeeded
Import-CSV $Filepath | %{if([string]::IsNullOrEmpty($_."Service from Dates") -And !([string]::IsNullOrEmpty($_."Service to Dates"))){$_."Service from Dates" = $_."Service to Dates"} ; $_} | Export-CSV $NewFilepath -UseQuotes AsNeeded
Import-CSV $Filepath | %{if(($_."Financial Class" -eq "Self-Pay")){$_."Payer" = $_."Health Plan Identification Number" = $_."Financial Class"} ; $_} | Export-CSV $NewFilepath -UseQuotes AsNeeded
我正在尝试尝试的一件事是使用 Switch cmdlet 而不是超级嵌套的 If 函数。我对 Switch 的想法有点像在 VBA 中使用“With”语句和执行所有真实案例的 Select Case。因此,而不是Switch($_.FirstProperty)
甚至If($_.FirstProperty)
可以我只是说Switch($_)
然后将每个属性/列引用为.FirstProperty
?唉,我不认为它会那样工作 - 但如果确实如此,那么我想我的代码将如下所示:
Import-CSV $Filepath | %{
Switch($_) {
[string]::IsNullOrEmpty($_."Type of Admission"){$_."Type of Admission" = "9"}
[string]::IsNullOrEmpty($_."Service from Dates") -And !([string]::IsNullOrEmpty($_."Service to Dates")){$_."Service from Dates" = $_."Service to Dates"}
($_."Financial Class" -eq "Self-Pay"){$_."Payer" = $_."Health Plan Identification Number" = $_."Financial Class"}
}
Export-CSV $NewFilepath -UseQuotes AsNeeded}
编辑:对于计划使用Cpt.Whale将数据保存在内存中而不是每行写入磁盘的建议的任何人;它的工作方式与您预期的相似,但 CSV 数据与您的标准 Get-Content/Set-Content 工作流程相比有点特别。具体来说,变量 like$report
将需要特殊特性。我目前的建议是使用$outFile = New-Object System.Collections.ArrayList
.Add 方法来进行填充。有人会说这很糟糕,但这个问题可能不会在列表中排名太靠前,而且速度快而且有效。
解决方案
首先,有一些方法可以一次读取一行文件,但它们通常是不必要的,除非内存不足,例如千兆字节以上的 csv 文件。如果是这种情况,那么我相信您想使用System.IO.File
这样的加速器而不是Import-CSV
:
foreach($row in [System.IO.File]::ReadLines($Filepath)) {
# Do Stuff to $row
}
此问题的答案中有更多示例,但您需要小心文件流锁定,这可能会很痛苦。
此外,可以通过同时处理所有if
语句来节省大量时间,而不是遍历整个文件 3 次。例如:
# Import once if you have the memory.
$data = Import-CSV $Filepath
# Iterate once
Foreach ($row in $data) {
if ( [string]::IsNullOrEmpty($row."Type of Admission") ) {
$row."Type of Admission" = "9"
}
if ( [string]::IsNullOrEmpty($row."Service from Dates") -And -Not ([string]::IsNullOrEmpty($row."Service to Dates")) ) {
$row."Service from Dates" = $row."Service to Dates"
}
if ( $row."Financial Class" -eq "Self-Pay" ) {
$row."Payer" = $row."Health Plan Identification Number" = $row."Financial Class"
}
# export finalized row
$row | Export-CSV $NewFilepath -UseQuotes AsNeeded
}
对于你关于Switch的最后一个问题,它只比较单个值,而不是对象。它对很多事情都很好,但除非你有更多的陈述要添加,否则这里就不适用。它更适合处理一列数据,例如if 'Type of Admission' is 1 then A; 2 then B;
等。
推荐阅读
- c# - Hangfire 仪表板页面显示 404
- azure-devops - Azure DevOps 中发布管道的测试服务器
- firebase - 看起来您正在尝试访问 functions.config().algolia 但那里没有任何价值
- vuejs2 - Vuetify - 关闭没有 v-dialog 的菜单对话框(使用激活器)
- python - 使用 Pandas MultiIndex 选择多行分层 DataFrame
- c# - SuppressMessage 不考虑 Resharper 的 MessageId
- python - 如何删除一元 +: 'str' 的错误错误操作数类型。在我的循环句子中
- java - 为什么这总是返回正分数?简单的代码
- python-3.x - Spotipy - 仅列出播放列表中的曲目和艺术家姓名
- docusignapi - 将 DocuSign WebHook 与沙盒中的 http 连接连接起来