Powershell - 从 csv 文件获取行并输出到不同 csv 文件的更快方法

2024-02-19

我有一个包含大约 250,000 行的 csv 文件。此 csv 文件中的第一个标题是“营销活动参考代码”。我还有一个需要在第一列中查找的活动参考代码列表(即 COLMABQ140、COLMABQ141)。如果我在第一列中找到此活动参考代码,我想将该活动代码的信息(即地址、联系日期等)输出到单独的 csv 文件中。我有许多这样的代码,需要生成许多特定于每个单独的活动代码的单独文件。 我实际上已经设法为此获得了一个工作脚本,但运行需要一个多小时,我想找到一种更快的方法来处理该文件。 基本上,我创建一个活动代码数组,然后使用 Import-csv 循环遍历它们,如果找到匹配项,则使用 E​​xport-csv 导出到单独的文件(请参阅下面的代码片段 - 有 20 个不同的 $refs 数组&对应的 for 循环)。 就像我说的,它确实工作得很好,因为它以我指定的格式获取了我需要的信息,但必须有一种更快的方法......即使原始文件是一百万行的四分之一!!

$file = 'Orig.csv'
$newfile = "File1.$today.csv"
        
$refs = @('COLMABQ140','COLMABQ141','COLMABQ142','COLMABQ143','COLMABQ144','COLMABQ176','COLMABQ177','COLMABQ178','COLMABQ179','COLMABQ180')

    foreach ($ref in $refs) {

        Import-csv $file | Where-Object {$_.'Campaign Ref Code' -like "$ref"} | Export-CSV -notype -Path $workdir\$newfile -Append 
    
    }
        
$newfile = "File2.$today.csv"
        
$refs = @('COLMABP140','COLMABP141','COLMABP142','COLMABP143','COLMABP144','COLMABP176','COLMABP177','COLMABP178','COLMABP179','COLMABP180')

    foreach ($ref in $refs) {

        Import-csv $file | Where-Object {$_.'Campaign Ref Code' -like "$ref"} | Export-CSV -notype -Path $workdir\$newfile -Append 
    
    }
        
$newfile = "File3.$today.csv"
        
$refs = @('COLMABS140','COLMABS141','COLMABS142','COLMABS143','COLMABS144','COLMABS176','COLMABS177','COLMABS178','COLMABS179','COLMABS180')

    foreach ($ref in $refs) {

        Import-csv $file | Where-Object {$_.'Campaign Ref Code' -like "$ref"} | Export-CSV -notype -Path $workdir\$newfile -Append 
    
    }
            

您的脚本的性能问题是:

  • 您将多次迭代Orig.csv输入文件。
    使用您的文件和特定的内容创建哈希表会更快$refs要测试的值。
  • 您将多次重新打开输出文件以附加到它。
    为此,使用(3)stepablepipelines 速度更快,请参阅:SteppablePipeline 有什么好处 https://stackoverflow.com/a/73074477/1701026.
    请注意正确设置PowerShell管道 https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_pipelines内存使用率较低。
  • The -eq运算符可能比-like操作员
    (显然你不需要-like运算符,因为值中没有任何通配符。)
    您可能只是依赖于常见的比较运算符 https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_comparison_operators特征:

当运算符的输入是标量值时,该运算符返回布尔值。当输入是集合时,运算符返回与表达式右侧值匹配的集合元素。如果集合中没有匹配项,比较运算符将返回一个空数组。

$workdir = ...
$refs =@{
    "File1.csv" = 'COLMABQ140','COLMABQ141','COLMABQ142','COLMABQ143','COLMABQ144','COLMABQ176','COLMABQ177','COLMABQ178','COLMABQ179','COLMABQ180'
    "File2.csv" = 'COLMABP140','COLMABP141','COLMABP142','COLMABP143','COLMABP144','COLMABP176','COLMABP177','COLMABP178','COLMABP179','COLMABP180'
    "File3.csv" = 'COLMABS140','COLMABS141','COLMABS142','COLMABS143','COLMABS144','COLMABS176','COLMABS177','COLMABS178','COLMABS179','COLMABS180'
}

$Pipelines = @{}
Import-csv .\Orig.csv |ForEach-Object -Begin {
    foreach ($file in $refs.keys) {
        $Pipelines[$file] = { Export-CSV -notype -Path "$workdir\$file" }.GetSteppablePipeline()
        $Pipelines[$file].Begin($True)
    }
} -Process {
    foreach ($file in $refs.keys) {
        if ($refs[$file] -eq $_.'Campaign Ref Code') { $Pipelines[$file].Process($_) }
    }
} -End {
    foreach ($file in $refs.keys) {
        $Pipelines[$file].End()
    }
}

掌握(可步进)管道
的力量PowerShell管道 https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_pipelines经常被误解和低估(特别是被不具有类似功能的语言的经验丰富的程序员所误解和低估)。因此,我写了一篇 PowerShell 社区博文:掌握(可步进)管道 https://devblogs.microsoft.com/powershell-community/mastering-the-steppable-pipeline/.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Powershell - 从 csv 文件获取行并输出到不同 csv 文件的更快方法 的相关文章

随机推荐