2017-06-12 52 views
0

我有大约5GB的logdata需要过滤并找到匹配的行,然后在匹配行中包含+/- 75行。如果数据的格式很重要,那么就是在缺少一些标签的XML中。从大型文本文件中导出行的范围

我的代码,用火柴找到行:

$ExampleFile = [System.IO.File]::ReadLines("C:\temp\filestomove\ExampleLog.txt") 
$AccountNumber = "*123456789*" 
$LineCount = 0 
$RowsToExport = @() 
foreach($line in $ExampleFile){ 

    if($line -like "*$AccountNumber*"){ 
    $RowsToExport += $LineCount 
    } 
    $LineCount += 1 
} 

上面的代码相当迅速做这项工作,它管理着约MB的日志每秒。这是一种我可以忍受的速度,因为这是一次性的工作。

我在努力的是以不是很慢的方式导出匹配的行。

我对于当前的代码看起来是这样的:

foreach($row in $RowsToExport){ 
$IndexRangeHigh = [int]$row + 75 
$IndexRangeLow = [int]$row - 75 

$test | select -Index ($IndexRangeLow..$IndexRangeHigh) | out-file C:\temp\Example.txt -append 
} 

这需要很长一段时间,我有我的使用select -index我怀疑这是非常缓慢的疑虑。以上

措施命令给了我下面的结果上的50MB测试文件:

TotalDays   : 0,00354806909375 
TotalHours  : 0,08515365825 
TotalMinutes  : 5,109219495 
TotalSeconds  : 306,5531697 
TotalMilliseconds : 306553,1697 

在阅读文件和匹配的行只用了55秒。

总之一切都交给一个问题:

如何从一个大的变量导出行范围?有没有其他方法可以用来从$ ExampleFile变量中选择行而不是使用select -index ($ExampleRangeLow..$ExampleRangeHigh)

+0

想通这可能是类似的东西。我会看看我是否可以改编我的代码来使用StreamReader。不要认为它应该是一个问题 – Jakodns

+1

不要将大文件读入内存。当输入文件变大并且系统开始交换时,它最终会导致系统停止工作。使用'Select-String -Context 75'来提取比赛前后的线。 –

回答

3

PowerShell有一个cmdlet(Select-String),允许提取文本和/或匹配后。

Select-String -Path 'C:\path\to\your.log' -Pattern '123456789' -Context 75 

Select-String输出与几个属性的对象,因此,如果您需要在文本格式匹配的行额外的代码是必需的:

... | ForEach-Object { 
    $pre = $_.Context.PreContext | Out-String 
    $post = $_.Context.PostContext | Out-String 

    "{0}{1}`n{2}" -f $pre, $_.Line, $post 
}