Performance Powershell—在不消耗大量内存的情况下获得两个文件的差异—是否有其他c#或c++;应用程序编程接口?

Performance Powershell—在不消耗大量内存的情况下获得两个文件的差异—是否有其他c#或c++;应用程序编程接口?,performance,powershell,compare,Performance,Powershell,Compare,我有两个大文件要比较(超过10GB)。下面的命令适用于小文件,但似乎占用了我机器上的RAM空间 如何在不消耗大量内存的情况下获得两个文件的差异 任何想法都将不胜感激 robocopy.exe C:\Folder\ C:\Folder\ /l /nocopy /is /e /fp /ns /nc /njh /njs /tee /log:c:\temp\FolderList.txt $path = 'C:\Folder\' $pattern = [regex]::Escape($path) $n

我有两个大文件要比较(超过10GB)。下面的命令适用于小文件,但似乎占用了我机器上的RAM空间

如何在不消耗大量内存的情况下获得两个文件的差异

任何想法都将不胜感激

robocopy.exe C:\Folder\ C:\Folder\ /l /nocopy /is /e /fp /ns /nc /njh /njs /tee  /log:c:\temp\FolderList.txt

$path = 'C:\Folder\'
$pattern = [regex]::Escape($path)
$newContent = @()
Get-Content -Path "c:\temp\FolderList.txt" | ForEach-Object {$newContent += $_ -replace $pattern, ''}
Set-Content -Path "c:\temp\FolderList.txt" -Value $newContent

(Get-Content C:\temp\FolderList.txt).Trim() -ne '' | Set-Content C:\temp\FolderList.txt

robocopy.exe C:\Folder2\ C:\Folder2\ /l /nocopy /is /e /fp /ns /nc /njh /njs /tee  /log:c:\temp\FolderList2.txt

$path = 'C:\Folder2\'
$pattern = [regex]::Escape($path)
$newContent = @()
Get-Content -Path "c:\temp\FolderList2.txt" | ForEach-Object {$newContent += $_ -replace $pattern, ''}
Set-Content -Path "c:\temp\FolderList2.txt" -Value $newContent

(Get-Content C:\temp\FolderList2.txt).Trim() -ne '' | Set-Content C:\temp\FolderList2.txt

Compare-Object -ReferenceObject (Get-Content c:\temp\FolderList.txt) -DifferenceObject (Get-Content c:\temp\FolderList2.txt)

最后更新

Folderlist.txt

C:\Folder\Data2\Documents\
        C:\Folder\Data2\Documents\1.txt
        C:\Folder\Data2\Documents\2.txt
        C:\Folder\Data2\Documents\3.txt
        C:\Folder\Data2\Documents\4.txt
        C:\Folder\Data2\Documents\5.txt
CompareLog1.txt

Data2\Documents\
C:\Folder\Data2\Documents\
        Data2\Documents\1.txt
        C:\Folder\Data2\Documents\1.txt
        Data2\Documents\2.txt
        C:\Folder\Data2\Documents\2.txt
        Data2\Documents\3.txt
        C:\Folder\Data2\Documents\3.txt
        Data2\Documents\4.txt
        C:\Folder\Data2\Documents\4.txt
        Data2\Documents\5.txt
        C:\Folder\Data2\Documents\5.txt
期望输出:

Data2\Documents\
Data2\Documents\1.txt
Data2\Documents\2.txt
Data2\Documents\3.txt
Data2\Documents\4.txt
Data2\Documents\5.txt
更新-2:

输出:

Data2\Documents\
C:\Folder\Data2\Documents\
Data2\Documents\1.txt
C:\Folder\Data2\Documents\1.txt
Data2\Documents\2.txt
C:\Folder\Data2\Documents\2.txt
Data2\Documents\3.txt
C:\Folder\Data2\Documents\3.txt
Data2\Documents\4.txt
C:\Folder\Data2\Documents\4.txt
Data2\Documents\5.txt
C:\Folder\Data2\Documents\5.txt

首先,使用
+=
向数组中添加内容是一种已知的内存占用,因为数组具有固定的长度,当您向数组中添加新元素时,需要在内存中重建完整的数组

因此,对于替换和删除每个日志文件的空行,我建议这样做:

robocopy.exe C:\Folder\ C:\Folder\ /l /nocopy /is /e /fp /ns /nc /njh /njs /tee  /log:c:\temp\FolderList.txt
robocopy.exe C:\Folder2\ C:\Folder2\ /l /nocopy /is /e /fp /ns /nc /njh /njs /tee  /log:c:\temp\FolderList2.txt

$path    = 'C:\Folder\'
$newFile = 'C:\temp\CompareLog_1.txt'  # have it create a new file instead of gathering all 10Gb in memory
$pattern = [regex]::Escape($path)
# use 'switch' to parse the log file line-by-line
# and write the processed lines to the new file.
# this will be lean on mmory, but takes a lot of disk write actions..
switch -Regex -File 'C:\temp\FolderList.txt' {
    $pattern { Add-Content $newFile -Value ($_ -replace $pattern).Trim() }
    default  { if ($_ -match '\S') { Add-Content $newFile -Value $_.Trim() }}  # non-empty or whitespace-only lines
}
对于第二个日志文件:

$path    = 'C:\Folder2\'
$newFile = 'C:\temp\CompareLog_2.txt'
$pattern = [regex]::Escape($path)
switch -Regex -File 'C:\temp\FolderList2.txt' {
    $pattern { Add-Content $newFile -Value ($_ -replace $pattern).Trim() }
    default  { if ($_ -match '\S') { Add-Content $newFile -Value $_.Trim() }}
}
接下来,您需要将新文件
CompareLog_1.txt
CompareLog_2.txt
进行比较,但我想这些文件可能仍然很大,因此我同意最好使用专用软件

根据您希望看到的结果,您也可以考虑使用旧的代码> Fc.exe < /Cord>,它运行速度快,不占用内存。 差不多

fc.exe  /C /N 'C:\temp\CompareLog_1.txt' 'C:\temp\CompareLog_2.txt'

不使用
添加内容
,而是使用StreamWriter,可以加快要比较的文件的写入速度: (这将创建Utf8NoBOM编码的文件)


为什么不能依赖外部命令行工具,如默认的Windows工具
comp.exe
或Microsoft utility
WindDiff
winmerge
来获取差异/修补程序?只是想澄清一下,您是否专门尝试区分两个robocopy日志文件?或者您正在尝试比较两个文件系统文件夹,而robocopy正是您尝试实现这一目标的途径?您是否专门尝试区分两个robocopy日志文件?是的,我希望有一种方法可以从两个文件中一次流一行,比如
获取内容file1,file2 |%{compare object$[0]$[1]}
,但它不起作用。好的,谢谢,但是修剪函数不能正确地用于脚本。我已经更新了我的问题。(5/11)我尝试了StreamWriter:和您的第一个脚本。但是没有运气。顺便说一句,我的原始脚本确实正确地修剪了它。@Arbelac-Ah。。错过了修剪()。在nowstill中添加了:)我已经添加了名为UPDATE-2的输出,有什么评论吗?
$path    = 'C:\Folder\'
$newFile = 'C:\temp\CompareLog_1.txt'
$writer  = [System.IO.StreamWriter]::new($newFile)
$pattern = [regex]::Escape($path)
switch -Regex -File 'C:\temp\FolderList.txt' {
    $pattern { $writer.WriteLine(($_ -replace $pattern).Trim()) }
    default  { if ($_ -match '\S') { $writer.WriteLine($_.Trim()) }}
}
# clean up
$writer.Flush()
$writer.Dispose()

$path    = 'C:\Folder2\'
$newFile = 'C:\temp\CompareLog_2.txt'
$writer  = [System.IO.StreamWriter]::new($newFile)
$pattern = [regex]::Escape($path)
switch -Regex -File 'C:\temp\FolderList2.txt' {
    $pattern { $writer.WriteLine(($_ -replace $pattern).Trim()) }
    default  { if ($_ -match '\S') { $writer.WriteLine($_.Trim()) }}
}
# clean up
$writer.Flush()
$writer.Dispose()