更新:我有一个工作脚本来完成任务。我需要批处理一堆文件,因此它接受了一个格式为文件名,OriginalHex,correctedHex的CSV文件。即使将搜索限制在第一个512字节之后,它也非常慢。它可能会写得更好,更快。感谢您的帮助。
更新2:修改搜索方法要更快,但远远不如专用的十六进制编辑器快。请注意,这是记忆密集型的。在RAM中的文件大小约为32倍。10MB = 320MB RAM。100MB = 3.2GB的RAM。我不建议大文件。它还保存到新文件而不是覆盖。原始文件重命名为file.ext_original@date time。
Import-CSV $PSScriptRootHEXCorrection.csv | ForEach-Object {
$File = $_.'FileName'
$Find = $_.'OriginalHEX'
$Replace = $_.'CorrectedHEX'
IF (([System.IO.File]::Exists("$PSScriptRoot$File"))) {
$Target = (Get-ChildItem -Path $PSScriptRoot$File)
} ELSE {
Write-Host $File "- File Not Found`n" -ForegroundColor 'Red'
RETURN
}
Write-Host "File: "$Target.Name`n"Find: "$Find`n"Replace: "$Replace
$TargetLWT = $Target.LastWriteTime
$TargetCT = $Target.CreationTime
IF ($Target.IsReadOnly) {
Write-Host $Target.Name "- Is Read-Only`n" -ForegroundColor 'Red'
RETURN
}
$FindLen = $Find.Length
$ReplaceLen = $Replace.Length
$TargetLen = (1..$Target.Length)
IF (!($FindLen %2 -eq 0) -OR !($ReplaceLen %2 -eq 0) -OR
[String]::IsNullOrEmpty($FindLen) -OR [String]::IsNullOrEmpty($ReplaceLen)) {
Write-Host "Input hex values are not even or empty" -ForegroundColor 'DarkRed'
RETURN
} ELSEIF (
$FindLen -ne $ReplaceLen) {
Write-Host "Input hex values are different lengths" -ForegroundColor 'DarkYellow'
RETURN
}
$FindAsBytes = New-Object System.Collections.ArrayList
$Find -split '(.{2})' | ? {$_} | % { $FindAsBytes += [Convert]::ToInt64($_,16) }
$ReplaceAsBytes = New-Object System.Collections.ArrayList
$Replace -split '(.{2})' | ? {$_} | % { $ReplaceAsBytes += [Convert]::ToInt64($_,16) }
# ^-- convert to base 10
Write-Host "Starting Search"
$FileBytes = [IO.File]::ReadAllBytes($Target)
FOREACH ($Byte in $FileBytes) {
$ByteCounter++
IF ($Byte -eq [INT64]$FindAsBytes[0]) { TRY {
(1..([INT64]$FindAsBytes.Count-1)) | % {
$Test = ($FileBytes[[INT64]$ByteCounter-1+[INT64]$_] -eq $FindAsBytes[$_])
IF ($Test -ne 'True') {
THROW
}
}
Write-Host "Found at Byte:" $ByteCounter -ForegroundColor 'Green'
(0..($ReplaceAsBytes.Count-1)) | % {
$FileBytes[[INT64]$ByteCounter+[INT64]$_-1] = $ReplaceAsBytes[$_]}
$Found = 'True'
$BytesReplaces = $BytesReplaces + [INT64]$ReplaceAsBytes.Count
}
CATCH {}
}
}
IF ($Found -eq 'True'){
[IO.File]::WriteAllBytes("$Target-temp", $FileBytes)
$OriginalName = $Target.Name+'_Original'+'@'+(Get-Date).ToString('yyMMdd-HHmmss')
Rename-Item -LiteralPath $Target.FullName -NewName $OriginalName
Rename-Item $Target"-temp" -NewName $Target.Name
#Preserve Last Modified Time
$Target.LastWriteTime = $TargetLWT
$Target.CreationTime = $TargetCT
Write-Host $BytesReplaces "Bytes Replaced" -ForegroundColor 'Green'
Write-Host "Original saved as:" $OriginalName
} ELSE {
Write-Host "No Matches" -ForegroundColor 'Red'}
Write-Host "Finished Search`n"
Remove-Variable -Name * -ErrorAction SilentlyContinue
} # end foreach from line 1
PAUSE
原始:以前曾提出过要求,但没有找到解决方案来执行简单直接的发现值并替换大型文件100MB 上的十六进制值。最好是针对此任务的命令行支持的十六进制编辑器的任何建议。
这是第一个裂缝:
(get-content -encoding byte file) -replace 'b10b',11 -as 'byte[]'
我正在检查其他链接,但是搜索和替换的唯一答案是一些错误。我投票重新开放。Mklement0一个人很近。他们都没有搜索,然后打印替换的位置。
没关系。您的速度更快,使用较少的内存。