【问题标题】:Powershell script been running for days when doing comparison进行比较时,Powershell 脚本已经运行了好几天
【发布时间】:2021-07-28 19:24:02
【问题描述】:

我收到了一个 powershell 查询,它适用于少量数据,但我正在尝试针对其中包含多个文件夹和文件的文件夹运行我的 CSV。文件夹大小接近 800GB,内有 180 个文件夹。

我想查看文件夹中是否存在该文件,我可以在 Windows 中手动搜索文件,并且返回结果不需要很长时间,但我的 CSV 有 3000 行,我不希望对 3000 行执行此操作.我的脚本适用于少量数据。

该脚本已运行 6 天,但尚未生成包含数据的文件。它是 0KB,我正在通过任务调度程序运行它。

脚本如下。

$myFolder = Get-ChildItem 'C:\Test\TestData' -Recurse -ErrorAction 
SilentlyContinue -Force
$myCSV = Import-Csv -Path 'C:\Test\differences.csv' | % {$_.'name' -replace "\\", ""}
$compare = Compare-Object -ReferenceObject $myCSV -DifferenceObject $myFolder

Write-Output "`n_____MISSING FILES_____`n" 
$compare

Write-Output "`n_____MISSING FILES DETAILS____`n"
foreach($y in $compare){
if($y.SideIndicator -eq "<="){
write-output "$($y.InputObject) Is present in the CSV but not in Missing folder." 

}
} 

然后我创建了另一个脚本,它运行上述脚本并包含一个输出文件命令并与任务调度程序一起运行。 C:\test\test.ps1 |输出文件 'C:\test\Results.csv'

有更好的方法吗?

谢谢

【问题讨论】:

  • compare-object -syncwindow 1 会做这项工作吗?否则,它将每一行与每一行进行比较。
  • C:\Test\differences.csv 中的示例行可能也会有所帮助。对于您尝试做的事情,可能有一条更快的路线,采用不同的方法而不是Compare-Object,这可能是比较文件大小、上次写入时间等,而您所关心的可能只是文件名。
  • @js2010 我以前从未见过该命令,它有什么作用-syncwindow 1?
  • 它只会比较每个文件中上下 1 行。否则,它将所有行与所有行进行比较,顺序无关紧要。对于大文件,默认的同步窗口非常慢。您还需要指定要比较的属性。
  • @newbie9803 - 列标题和示例行会很有用。

标签: powershell powershell-2.0 powershell-3.0 powershell-4.0


【解决方案1】:

有更好的方法吗?

是的!

  1. 将磁盘上的每个文件名添加到HashSet[string]
    • HashSet 类型在确定它是否包含 具体值与否,比Compare-Object
    • 快很多
  2. 遍历您的 CSV 记录,检查每个文件名是否存在于步骤 1 中的集合中

# 1. Build our file name index using a HashSet
$fileNames = [System.Collections.Generic.HashSet[string]]::new()
Get-ChildItem 'C:\Test\TestData' -Recurse -ErrorAction 
SilentlyContinue -Force |ForEach-Object {
  [void]$fileNames.Add($_.Name)
}

# 2. Check each CSV record against the file name index
Import-Csv -Path 'C:\Test\differences.csv' |ForEach-Object {
  $referenceName = $_.name -replace '\\'
  if(-not $fileNames.Contains($referenceName)){
    "${referenceName} is present in CSV but not on disk"
  }
}

另一种选择是在Where-Object 过滤器中使用步骤 1 中的哈希集:

$csvRecordsMissingFromDisk = Import-Csv -Path 'C:\Test\differences.csv' |Where-Object { -not $fileNames.Contains($_) }

【讨论】:

  • 您好,感谢您的意见!我已经对此进行了测试,但它向我展示了文件夹中的内容,而不是 csv 上存在但硬盘上不存在的丢失文件。
  • @newbie9803 我的错,我忘了-not - 现在更新了:)
  • 谢谢,我将在大数据上对此进行测试,我将如何在输出中引入其他列,因为它只显示文件名,differences.csv 中的另一列将是“地点”。再次感谢:)
  • $_ 包含整个记录,因此$_.location 将解析为location 列值,就像$_.name 解析为name 列值一样:)
  • 效果很好,今天学到了新东西!总是在 powershell 上学习新东西!谢谢你的回答!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-05
  • 2017-03-09
  • 1970-01-01
  • 1970-01-01
  • 2020-12-27
相关资源
最近更新 更多