Travenin
Travenin

Reputation: 1590

How to find and replace within a large binary file with PowerShell?

I have binary files larger than 50 GB, which contain a specific string I want to replace with equal length all-spaces string. The string I am looking for is in the beginning of file, say within the first megabyte. How can I do this with PowerShell?

I am afraid [System.IO.File]::ReadAllBytes("myfile.bin") is not the solution, because I don't want to load the whole binary. I want to search and replace within the first megabyte.

Upvotes: 1

Views: 4850

Answers (1)

Mikhail Tumashenko
Mikhail Tumashenko

Reputation: 1723

Adopted from C#, so some refactoring might be needed:

$path = "\path\to\binary\file"

$numberOfBytesToRead = 1000000

$stringToSearch = "Hello World!"
$enc = [system.Text.Encoding]::UTF8
[Byte[]]$replacementString = $enc.GetBytes("     ");

$fileStream = [System.IO.File]::Open($path, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite)

# binary reader to search for the string 
$binaryReader = New-Object System.IO.BinaryReader($fileStream)

# get the contents of the beginning of the file
[Byte[]] $byteArray = $binaryReader.ReadBytes($numberOfBytesToRead)

# look for string
$m = [Regex]::Match([Text.Encoding]::ASCII.GetString($byteArray), $stringToSearch)
if ($m.Success)
{    
    echo "Found '$stringToSearch' at position "$m.Index
}
else
{
    echo "'$stringToSearch' was not found"
}
$fileStream.Close()

# reopen to write
$fileStream = [System.IO.File]::Open($path, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Write, [System.IO.FileShare]::ReadWrite)

$binaryWriter = New-Object System.IO.BinaryWriter($fileStream)

# set file position to location of the string
$binaryWriter.BaseStream.Position = $m.Index; 
$binaryWriter.Write($replacementString)

$fileStream.Close()

Upvotes: 6

Related Questions