Powershell CSV拆分会导致错误

Powershell CSV拆分会导致错误,powershell,csv,locking,export-to-csv,Powershell,Csv,Locking,Export To Csv,你能帮我解决下面描述的问题吗 我用PS编写了一个脚本,试图将大型CSV文件(30000行/6MB)拆分为较小的文件。新文件以第1列和第2列内容的混合形式命名。若文件已存在,则脚本仅追加新行 主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

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

我用PS编写了一个脚本,试图将大型CSV文件(30000行/6MB)拆分为较小的文件。新文件以第1列和第2列内容的混合形式命名。若文件已存在,则脚本仅追加新行

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

导出Csv:进程无法访问文件“C:\xxx\xxx\xxx.Csv”,因为 它正在被另一个进程使用


导出Csv
是同步的
-当它返回时,输出文件已经关闭-因此问题中的代码不能解释问题

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

如果所有输出文件都可以在循环后通过单个
导出Csv
调用来完全创建,那么问题应该会消失,正如Lee所建议的那样。无论怎样,这对于性能来说都是首选的,但是假设整个CSV文件作为一个整体放入内存中

下面是一个基于
组对象
的解决方案,该解决方案使用单个管道来实现完整功能的写入每个输出文件:

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软件干扰的替代解决方案。

导出Csv
是同步的
-当它返回时,输出文件已经关闭-因此问题中的代码无法解释问题

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

如果所有输出文件都可以在循环后通过单个
导出Csv
调用来完全创建,那么问题应该会消失,正如Lee所建议的那样。无论怎样,这对于性能来说都是首选的,但是假设整个CSV文件作为一个整体放入内存中

下面是一个基于
组对象
的解决方案,该解决方案使用单个管道来实现完整功能的写入每个输出文件:

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 On Access Scan,它正在扫描创建的每个文件。有3种方法可以绕过此问题:

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

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

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

文件写入需要时间。我的猜测是,您的循环将在上一次写入完成之前进入下一次写入。解决方案[以及一个相当大的加速]是将每种类型的数据保存到$var中,然后在循环完成后将整个集合保存到一个文件中。//此外,您可能希望停止重复
“$($row.OS.Type')-$($row.Site)”
,并将其保存到临时$Var以供重复使用。对每一行多次计算该字符串可能会使速度减慢一点。@Lee_Dailey:Good tips重新加速,但是
Export Csv
应该是同步的,所以问题中的代码不能解释问题。试试下面的方法-我还没有看到它失败(也不希望它失败):
$co=[pscustomobject]@{one=1;two=2;two=3};ri-ea忽略t.csv;foreach($i in 1..1e3){$co | Export Csv-append t.Csv-NoTypeInformation}
@ArPy,在写文件的过程中会有一个无关的进程访问这些文件吗?@Lee_Dailey/mklement0-你说得对。。。是Mcafee在Access扫描模块上访问每个新创建的文件。当下一个循环试图附加新数据时,OAS正在扫描这些文件。谢谢你的帮助@阿皮-谢谢你的“为什么”。请你把它作为一个答案或者作为一个便条添加到你原来的帖子里好吗;我认为这应该得到一个正确的答案。坦率地说,我对杀毒软件可能导致如此隐蔽的故障感到困惑。文件写入需要时间。我的猜测是,您的循环将在上一次写入完成之前进入下一次写入。解决方案[以及一个相当大的加速]是将每种类型的数据保存到$var中,然后在循环完成后将整个集合保存到一个文件中。//此外,您可能希望停止重复
“$($row.OS.Type')-$($row.Site)”
,并将其保存到临时$Var以供重复使用。对每一行多次计算该字符串可能会使速度减慢一点。@Lee_Dailey:Good tips重新加速,但是
Export Csv
应该是同步的,所以问题中的代码不能解释问题。试试下面的方法-我还没有看到它失败(也不希望它失败):
$co=[pscustomobject]@{one=1;two=2;two=3};ri-ea忽略t.csv;foreach($i in 1..1e3){$co | Export Csv-append t.Csv-NoTypeInformation}
@ArPy,在写文件的过程中,会有一个无关的进程访问这些文件吗?@Lee_Dailey/mklement0-your