Performance Powershell—在不消耗大量内存的情况下获得两个文件的差异—是否有其他c#或c++;应用程序编程接口?
我有两个大文件要比较(超过10GB)。下面的命令适用于小文件,但似乎占用了我机器上的RAM空间 如何在不消耗大量内存的情况下获得两个文件的差异 任何想法都将不胜感激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
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 utilityWindDiff
或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()