我有一个脚本,用于检查文件2中是否存在文件1中的URL,如果不存在,则将其写入输出文件。它工作正常,这是:
Write-Host "Script output will have unique items from file 1"
$FirstPath = Read-Host -Prompt "Input file location of first .csv file"
$SecondPath = Read-Host -Prompt "Input file location of second .csv file"
Write-Host "Importing CSV files..."
$FirstFile = Import-Csv $FirstPath -Delimiter ';' |
Select-Object -ExpandProperty Url
$SecondFile = Import-Csv $SecondPath -Delimiter ';' |
Select-Object -ExpandProperty ITEM_TARGET_URI
Write-Host "Comparing files..."
Compare-Object -ReferenceObject $FirstFile -DifferenceObject $SecondFile -PassThru |
Where-Object { $_.SideIndicator -eq "<=" } |
Out-File -Encoding Utf8 .\result.txt
Write-Host "Done, press any key to continue..."
$x = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
我的问题是,当处理大型CSV文件(例如一个有4 000 000条记录)时,脚本工作了一整晚,但仍然没有完成。我也无法看到是否有任何进展。我想让它更快地工作,或者至少有一些关于工作进展的信息。我已经阅读了有关进度条等的信息。但由于它仅在一行中进行比较而不是循环,因此无法工作。
我可以在脚本中更改哪些内容以使其更快地运行和/或能够看到进度?
编辑:问题与网络模式不同,我主要专注于处理大文件和提高脚本速度。解决方案在那里没有回答这个问题。
答案 0 :(得分:1)
由于您显然只想要第一个文件中不存在于第二个文件中的网址,因此您可能需要尝试以下内容:
$ref = Import-Csv $SecondPath -Delimiter ';' |
Select-Object -Expand ITEM_TARGET_URI
Import-Csv $FirstPath -Delimiter ';' |
Select-Object -Expand Url |
Where-Object { $ref -notcontains $_ } |
Out-File -Encoding UTF8 .\result.txt
这假设Compare-Object
是您的实际瓶颈。您是否验证了(通过计算import语句和compare语句)?
如果比较操作不是主要瓶颈(例如,数据导入需要相同的长时间或更长时间),您可能希望用{/ p>之类的内容替换Import-Csv
$ref = Get-Content $SecondPath |
Select-Object -Skip 1 |
ForEach-Object { $_.Split(';')[5] }
或者像这样:
$reader = New-Object IO.StreamReader $SecondPath
[void]$reader.ReadLine() # skip header line
$ref = while ($reader.Peek() -gt 0) {
$reader.ReadLine().Split(';')[5]
}
$reader.Close(); $reader.Dispose()
将5
替换为要提取其值的列的索引。
附录:您应该能够通过使用哈希表查找而不是-notcontains
来大大加快处理速度。
$ref = @{}
Import-Csv $SecondPath -Delimiter ';' | ForEach-Object {
$ref[$_.ITEM_TARGET_URI] = $true
}
Import-Csv $FirstPath -Delimiter ';' |
Where-Object { -not $ref.ContainsKey($_.Url) } |
Select-Object -Expand Url |
Out-File -Encoding UTF8 .\result.txt
答案 1 :(得分:0)
$FirstFile | Where {$SecondFile -NotContains $_}