Saya memiliki dua file besar untuk dibandingkan (lebih dari 10 GB). Perintah di bawah ini berfungsi dengan baik untuk file kecil tetapi tampaknya memakan ruang RAM di mesin saya.

Bagaimana saya bisa mendapatkan perbedaan dua file tanpa menghabiskan banyak memori?

Pikiran apa pun akan sangat dihargai.

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)

PEMBAHARUAN TERAKHIR

Daftar folder.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

BandingkanLog1.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

Keluaran yang diinginkan:

Data2\Documents\
Data2\Documents\1.txt
Data2\Documents\2.txt
Data2\Documents\3.txt
Data2\Documents\4.txt
Data2\Documents\5.txt

PEMBARUAN -2:

Keluaran:

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
0
Arbelac 9 Mei 2021, 13:56

1 menjawab

Jawaban Terbaik

Pertama-tama, menambahkan hal-hal ke array dengan += adalah babi memori yang dikenal, karena array memiliki panjang tetap dan ketika Anda menambahkan elemen baru ke dalamnya, array lengkap perlu direkonstruksi dalam kenangan.

Jadi untuk penggantian dan menghapus baris kosong dari setiap file log, saya akan merekomendasikan melakukan itu seperti ini:

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
}

Dan untuk file log kedua:

$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() }}
}

Selanjutnya Anda perlu membandingkan file baru CompareLog_1.txt dengan CompareLog_2.txt, tetapi ini mungkin masih sangat besar saya kira, jadi untuk itu saya setuju dengan Zilog80 untuk menggunakan perangkat lunak khusus dengan sebaik-baiknya.

Bergantung pada apa yang ingin Anda lihat sebagai hasilnya, Anda juga dapat mempertimbangkan untuk menggunakan fc.exe lama yang bekerja cepat dan tidak haus memori.
Sesuatu seperti

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

Anda dapat mempercepat penulisan file untuk dibandingkan dengan tidak menggunakan Add-Content, tetapi StreamWriter: (ini akan membuat file dalam penyandian Utf8NoBOM)

$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()
0
Theo 12 Mei 2021, 14:34