Powershell昂贵的解析

时间:2009-03-24 06:37:17

标签: syntax powershell

来自剧本的一小部分我正在写作;

Get-Content $tempDir\$todaysLog | Where-Object { $_ -match "" } |
    ForEach-Object -Process {
    $fields = [regex]::split($_,'@|\s+')
    Add-Content -Path $importSource2\$todaysLog -value ($($fields[0]) + "`t"  + $($fields[1]) + "`t" + $($fields[2]) + " " + $($fields[3])+ "`t" + "<*sender*@"+($($fields[5])) + "`t" + "<*recipient*@"+($($fields[7])))
    }

对包装很抱歉,基本上它将文件的元素标记为一个数组,然后用它周围的一些其他文本写出某些元素。目的是用无意义的东西替换传递的发件人/收件人信息。

下面是我正在解析的日志文件示例;

10.197.71.28 SG 02012009 00:00:00&lt; ['recip@kpmg.com.sg']&gt;

显然我已经取代了我的样本中的地址信息。上面的部分工作得很好althgogh我意识到它非常昂贵。任何事情都可以想到一些更便宜的东西,也许是一个替换文本的选择字符串而不是标记/重写它?

干杯

3 个答案:

答案 0 :(得分:1)

cat $tempDir\$todaysLog |
  %{ [regex]::Replace($_, "[A-Z0-9._%+-]+(@[A-Z0-9.-]+\.[A-Z]{2,4}\s<\[')[A-Z0-9._%+-]+(@[A-Z0-9.-]+\.[A-Z]{2,4}'\]>)", '*sender*$1*recipients*$2', "IgnoreCase") } > $importSource2\$todaysLog

日志条目必须与示例行类似(特别是sender@kpmg.com&lt; ['recip@kpmg.com.sg']&gt;部分)。


编辑:我做了一些基准测试(1 mo文件(约15000行样本)):

Andy Walker的解决方案(使用 split ) - &gt;的 18,44s

Measure-Command {

Get-Content $tempDir\$todaysLog | Where-Object { $_ -match "" } |
    ForEach-Object -Process {
    $fields = [regex]::split($_,'@|\s+')
    Add-Content -Path $importSource2\$todaysLog -value ($($fields[0]) + "`t"  + $($fields[1]) + "`t" + $($fields[2]) + " " + $($fields[3])+ "`t" + "<*sender*@"+($($fields[5])) + "`t" + "<*recipient*@"+($($fields[7])))
    }

}

Dangph的解决方案(使用替换) - &gt;的 18,16s

Measure-Command {

Get-Content $tempDir\$todaysLog | Where-Object { $_ -match "" } |
    ForEach-Object -Process {
    $s2 = $_ -replace "\t[^@\t']+@", "`t*sender*@"
    $s3 = $s2 -replace "\<\['.+@", "<['*recipient*@"
    Add-Content -Path $importSource2\$todaysLog -value $s3
    }

}

Madgnome的解决方案(使用 regex ) - &gt;的 6,16s

Measure-Command {

cat $tempDir\$todaysLog |
  %{ [regex]::Replace($_, "[A-Z0-9._%+-]+(@[A-Z0-9.-]+\.[A-Z]{2,4}\s<\[')[A-Z0-9._%+-]+(@[A-Z0-9.-]+\.[A-Z]{2,4}'\]>)", '*sender*$1*recipients*$2', "IgnoreCase") } > $importSource2\$todaysLog

}

答案 1 :(得分:0)

$s1 = "10.197.71.28 SG  02012009 00:00:00   sender@kpmg.com <['recip@kpmg.com.sg']>"
$s2 = $s1 -replace "\t[^@\t']+@", "`t*sender*@"
$s3 = $s2 -replace "\<\['.+@", "<['*recipient*@"
write-host $s3

我假设所有日志条目看起来都像样本行。如果他们不这样做,那么我们可能需要更复杂一些。

注意如果您复制并粘贴上述代码,则可能需要在第一行的“发件人”之前手动重新插入制表符。

答案 2 :(得分:0)

您应该避免使用Powershell作为大文件大小日志解析的引擎。我会使用logparser.exe(你有一个可以转换为csv的空格分隔条目),然后在Powershell中使用import-csv来重新创建一个Powershell对象。从那里你可以剥离和替换字段(基于每个对象)。 Powershell是胶水而不是燃料。用它来解析任何大小的大型日志都不是完全愚蠢的,但对你和CPU来说都是昂贵的。尽管Lee Holmes在http://examples.oreilly.com/9780596528492/的书籍示例中有一个优秀的Convert-TextObject.ps1,但是你需要一种类型的日志解析引擎来处理繁重的工作。