需要在Powershell中写入输出文件的更有效方法

时间:2017-07-01 22:09:14

标签: regex powershell

我有一个Powershell脚本,我用它来解析文件中的每一行,重新格式化它,并将新字符串写入输出文件。它与几百行的输入文件一起工作正常。但是,我需要最终针对一个有几百万行的文件来运行它,我已经等了好几个小时但它还没有完成。在this post之后,我想我需要将写输出放在循环之外,但到目前为止我还没有成功。

这是我目前的代码:

Foreach ($line in Get-Content $logFile) {

    $arr = $line.Split()

    $port1 = $arr[9].Split(":")

    $port2 = $arr[11].Split(":")

    $connstring = '|' + $port1[0] + "|" + $port1[1] + "|" + $port2[0] + "|" + $port2[1] + "|" + $arr[4] + "|"

    Write-Output $connstring | Out-File "C:\logging\output\logout.txt" -Append 
}

输入字符串的示例是:

06/14-04:40:11.371923  [**] [1:4:0] other [**] [Priority: 0] {TCP} 67.202.196.92:80 -> 192.168.1.105:55043

我需要将其重新格式化为:

|67.202.196.92|80|192.168.1.105|55043|other|

非常感谢任何帮助!

3 个答案:

答案 0 :(得分:3)

如果在-ReadCount上使用Get-Content,它将一次一行地传输文件,而不必将整个文件读入内存。我怀疑在循环之外移动写操作可能会更快。循环中较少的变量和步骤也可能有所帮助。

假设分割后的第四个元素不包含冒号(你没有提供和你的文件的例子)那么这样的东西应该可以做到这一点:

Get-Content $logFile -ReadCount 1 | % {
    '|' + (($_.Split()[9, 11, 4] -replace ':', '|') -join '|') + '|' 
} | Out-File "C:\logging\output\logout.txt"

答案 1 :(得分:1)

可能有助于删除字符串构造中的添加

$connstring = "|$($port1[0])|$($port1[1])|$($port2[0])|$($port2[1])|$($arr[4])|"

尝试使用Measure-Command测试样本数据集。

答案 2 :(得分:1)

尝试这样的事情:

$test="06/14-04:40:11.371923  [**] [1:4:0] other [**] [Priority: 0] {TCP} 67.202.196.92:80 -> 192.168.1.105:55043"

$template=@"
{Row:06/14-04:40:11.371923  [**] [1:4:0] {Text:other} [**] [Priority: 0] \{TCP\} {IPIN:67.202.196.92}:{PORTIN:80} -> {IPOUT:192.168.1.105}:{PORTOUT:55043}}
"@

$test| ConvertFrom-String -TemplateContent $template |%{"|{0}|{1}|{2}|{3}|{4}|" -f $_.Row.IPIN, $_.Row.PORTIN, $_.Row.IPOUT , $_.Row.PORTOUT , $_.Row.Text }

但您可以像这样直接导出到csv:

$template=@"
{Row:06/14-04:40:11.371923  [**] [1:4:0] {Text:other} [**] [Priority: 0] \{TCP\} {IPIN:67.202.196.92}:{PORTIN:80} -> {IPOUT:192.168.1.105}:{PORTOUT:55043}}
"@

Get-Content $logFile | ConvertFrom-String -TemplateContent $template | % {
 [pscustomobject]@{
 IPIN=$_.Row.IPIN 
 PORTIN=$_.Row.PORTIN 
 IPOUT=$_.Row.IPOUT 
 PORTOUT=$_.Row.PORTOUT 
 Text=$_.Row.Text
 }

} | export-csv "C:\logging\output\logout.csv" -Append -NoType