CSV 拆分导致错误

CSV splitting causes errors

你能帮我解决下面描述的问题吗?

我在 PS 中编写了一个脚本,它试图将大型 CSV 文件(30 000 行/6MB)拆分为较小的文件。新文件被命名为第一列和第二列内容的混合。如果文件已经存在,脚本只会追加新行。

主要 CSV 文件示例:

Site;OS.Type;Hostname;IP address
Amsterdam;Server;AMS_SRVDEV01;10.10.10.12
Warsaw;Workstation;WAR-L4D6;10.10.20.22
Ankara;Workstation;AN-D5G36;10.10.13.22
Warsaw;Workstation;WAR-SRVTST02;10.10.20.33
Amsterdam;Server;LON-SRV545;10.10.10.244

PowerShell 版本:5.1.17134.858

function Csv-Splitter {
    $fileName = Read-Host "Pass file name to process: "

    $FileToProcess = Import-Csv "$fileName.csv" -Delimiter ';'
    $MyList = New-Object System.Collections.Generic.List[string]                                         

    foreach ($row in $FileToProcess) {
        if ("$($row.'OS.Type')-$($row.Site)" -notin $MyList) {
            $MyList.Add("$($row.'OS.Type')-$($row.Site)")
            $row | Export-Csv -Delimiter ";" -Append -NoTypeInformation "$($row.'OS.Type')-$($row.Site).csv"
        }
        else {
            $row | Export-Csv -Delimiter ";" -Append -NoTypeInformation "$($row.'OS.Type')-$($row.Site).csv"
        }
    }

}

基本上,代码工作正常,但是在循环处理时会不时产生一些错误。这会导致新文件中缺少某些行 - 缺少的行数等于错误数:

Export-Csv : The process cannot access the file 'C:\xxx\xxx\xxx.csv' because it is being used by another process.

Export-Csvsynchronous - 到它 returns 时,输出文件已经关闭- 所以问题中的代码没有解释问题

正如您在评论中确认的那样,根据 Lee_Dailey 的建议,罪魁祸首是 AV(防病毒)Mcafee 按访问扫描模块,它会在幕后访问每个新创建的文件,从而 暂时锁定它 ,导致 Export-Csv 间歇性失败。

如果所有输出文件都可以通过 单个 Export-Csv 调用每个 完全创建,那么 问题应该会消失,之后循环,正如 Lee 所建议的那样。无论如何,这 更适合性能 ,但假设整个 CSV 文件作为一个整体适合内存

这是一个基于 Group-Object 的解决方案,它使用单个管道来实现完整写入每个输出文件的功能:

function Csv-Splitter {

  $fileName = Read-Host "Pass file name to process: "

  Import-Csv "$fileName.csv" -Delimiter ';' | 
    Group-Object { $_.'OS.Type' + '_' + $_.Site + '.csv' } |
      ForEach-Object { $_.Group | Export-Csv -NoTypeInformation $_.Name }

}

显示了消除 AV 软件干扰的替代解决方案。

问题的根源是 McAfee 按访问扫描,它正在扫描创建的每个文件。有3种方法可以绕过这个问题:

  • a) 暂时禁用整个 AV/OAS 模块。
  • b) 将 powershell.exe 作为低风险流程添加到 OAS 策略中
  • c) 在内存中收集所有数据并使用 Export-CSV 创建所有文件,作为最后一步,如 .
  • 所示