function Remove-IdsFromFile {
param(
[Parameter(Mandatory=$true,Position=0)]
[string]$BigFile,
[Parameter(Mandatory=$true,Position=1)]
[Object[]]$IgnorePatterns
)
# Create the pattern matches
$regex = ($IgnorePatterns | ForEach-Object{[regex]::Escape($_)}) -join "|"
If(Test-Path $BigFile){
$reader = New-Object System.IO.StreamReader($BigFile)
$line=$reader.ReadLine()
while ($line -ne $null)
{
# Check if the line should be output to file
If($line -notmatch $regex){$line | Add-Content "CleansedBigFile.txt"}
# Attempt to read the next line.
$line=$reader.ReadLine()
}
$reader.close()
} Else {
Write-Error "Cannot locate: $BigFile"
}
}
StreamReader
— один из предпочтительных методов чтения больших текстовых файлов. Мы также используем регулярное выражение для создания строки шаблона для сопоставления на основе. В строке шаблона мы используем [regex]::Escape()
в качестве меры предосторожности, если присутствуют управляющие символы регулярного выражения. Придется угадывать, так как мы видим только одну строку шаблона.
Если $IgnorePatterns
можно легко преобразовать в строки, это должно работать нормально. Вот небольшой пример того, как выглядит $regex
:
XX000029|XX000028|XX000027
Если $IgnorePatterns
заполняется из базы данных, у вас может быть меньше контроля над этим, но, поскольку мы используем регулярное выражение, вы можете уменьшить этот набор шаблонов, действительно используя регулярное выражение (вместо простого большого альтернативного совпадения), например в моем примере выше. Вы можете уменьшить это, например, до XX00002[7-9]
.
Я не знаю, обеспечит ли само регулярное выражение повышение производительности с 1500 возможными. StreamReader
здесь должен быть в центре внимания. Однако я запятнал воду, используя Add-Content
для вывода, который также не получает никаких наград за быстроту (может использовать потоковую запись вместо этого).
Чтение и запись
Мне все еще нужно проверить это, чтобы убедиться, что это работает, но здесь используются только streamreader
и streamwriter
. Если это работает лучше, я просто заменю приведенный выше код.
function Remove-IdsFromFile {
param(
[Parameter(Mandatory=$true,Position=0)]
[string]$BigFile,
[Parameter(Mandatory=$true,Position=1)]
[Object[]]$IgnorePatterns
)
# Create the pattern matches
$regex = ($IgnorePatterns | ForEach-Object{[regex]::Escape($_)}) -join "|"
If(Test-Path $BigFile){
# Prepare the StreamReader
$reader = New-Object System.IO.StreamReader($BigFile)
#Prepare the StreamWriter
$writer = New-Object System.IO.StreamWriter("CleansedBigFile.txt")
$line=$reader.ReadLine()
while ($line -ne $null)
{
# Check if the line should be output to file
If($line -notmatch $regex){$writer.WriteLine($line)}
# Attempt to read the next line.
$line=$reader.ReadLine()
}
# Don't cross the streams!
$reader.Close()
$writer.Close()
} Else {
Write-Error "Cannot locate: $BigFile"
}
}
Вам может понадобиться некоторое предотвращение ошибок для потоков, но, похоже, оно работает на месте.
person
Matt
schedule
28.07.2015