解析文本类型日志文件

时间:2014-03-31 20:00:52

标签: html parsing powershell logfile

我今天刚刚开始使用PowerShell 我有这种类型的日志文件,包含任意数量的测试:

Plan test.pln - 1 error

    [#VERSION-TestPlanGenerator#]3.8.0.0018
    HW# VS4_1
    [#TC#] test 1
        \\APPS-EUAUTO1\C$\...\Temp\FXSAPIDebugLogFile.txt - The process cannot access the file because it is being used by another process.
        [APPS-EUAUTO1] [prep] Setting agent options and random seed...
        [APPS-EUAUTO1] [info] Initial Seed : 124426621
        [APPS-EUAUTO1] [info] Current seed : 96010
        [APPS-EUAUTO1] [info] rt1 t1
        [APPS-EUAUTO1] [debug] rt1 t1
        [#WARNING#][APPS-EUAUTO1] [warning] rt1 t1 ( Screen shot : D:\...\[APPS-EUAUTO1] 03-28-14 11-29-22.png)
        [#WARNING#][APPS-EUAUTO1] [warning] Unhandled error detected ! ( Screen shot : D:\...\[APPS-EUAUTO1] 03-28-14 11-29-22.png)
        [#ERROR#][APPS-EUAUTO1] [error] rt1 t1 ( Screen shot : D:...\[APPS-EUAUTO1] 03-28-14 11-29-22.png)
        Occurred in fnMsg at ..\functions\f_common.inc(456)
        Called from t1 at test.t(10)
        Called from rt1 at test.t(5)
    [#TC#] test 2
        [APPS-EUAUTO1] [prep] Setting agent options and random seed...
        [APPS-EUAUTO1] [info] Current seed : 177041
        [APPS-EUAUTO1] [info] rt2 t2
        [APPS-EUAUTO1] [debug] rt2 t2

我需要在每个元素中都有一个数组中的所有测试:

  • 字符串名称(例如:测试1)
  • 布尔错误(例如:对于测试1为true,因为有[#WARNING#] 或者出现[#ERROR#]消息)
  • 数组包含所有消息的消息(例如:对于测试2全部4 消息)

最后我想将此数组导出为html文件。

所有测试均以[#TC#]开头。 我在阅读部分遇到问题。 我尝试过来自不同网站的一些东西,但它似乎对我不起作用:

Function Import-MyLog1 {
    # -----------------------------------------------------------------------
    Function Get-Log {
    # Reads the log file into memory.
        Try {
            Get-Content -path "res.txt" -ErrorAction Stop -Delimiter "[#TC#]"
        }
        Catch {
            Write-Error "The data file is not present" 
            BREAK
        }
    } # End: Function Get-Log
    # -----------------------------------------------------------------------
    Function Get-Record {
    Param ($Log)
        for ($i=1; $i -lt $Log.Length; $i++) { # ignore the header
            $Testcase = $Log[$i]
            New-Object PSobject -Property @{
                Name = $Testcase[0]
                Data = $Testcase[3..6]
            }
        }
    } # End: Function Get-Record
    # Load the log into memory
    $Log = Get-Log
    $Records = Get-Record -Log $Log
    $Records # Added only to see the current progress. 
} #End: Function Import-MyLog1

clear
Import-MyLog1

这是谁可能需要一个例子的最终代码:

Function Get-TxtLog {
Param ($File)
# Reads the log file into memory.
    Try {
        Get-Content -path $File -ErrorAction Stop -Delimiter "[#TC#]"
    } Catch {
        Write-Error "The data file is not present" 
        BREAK
    }
} # End: Function Get-TxtLog

# -----------------------------------------------------------------------

Function Get-Testcase {
Param ($TxtLog)
    for ($i=1; $i -lt $TxtLog.Count; $i++) { # $i=1 to ignore the header
        $Testcase = $TxtLog[$i].split("`n")
        $Output = New-Object PSobject -Property @{
            Name     = $Testcase[0].Trim()
            Messages = $Testcase[1..($Testcase.count)] | ?{!($_ -match "\[#TC#]")} | ForEach-Object -process {$_.Trim()}
        }
        $Error = $( if($Output.Messages -match ("\[#ERROR#]|\[#WARNING#]")) {$true} else {$false} )
        $Output|Add-Member -MemberType NoteProperty -Name "Error" -value $Error
        $Output|Add-Member -MemberType NoteProperty -Name "Runtime" -value $null # will be added later
        $Output|Add-Member -MemberType NoteProperty -Name "Data" -value $null    # will be added later
        $Output # to pipe the object
    }
} # End: Function Get-Testcase

# -----------------------------------------------------------------------

# Load the log into memory
$TxtLog = Get-TxtLog -file "D:\XHostMachine\Results\res.txt"
$Records = Get-Testcase -TxtLog $TxtLog
$Records | Format-Table

1 个答案:

答案 0 :(得分:2)

如果你今天刚刚开始使用PowerShell,那么我只能在一年的时间里想象你将要做些什么......我认为你已经开始了。

现在,你似乎想把所有东西都变成一个功能,我认为它没有什么害处,但个人看来有点矫枉过正。当我将测试代码粘贴到我的ISE中时,我做的第一件事就是将第一行和第28行注释掉。似乎并不需要所有这些。

接下来,我在Get-Log函数中添加了一个参数,以便根据需要提供路径,如果排除它,则默认为res.txt文件。

Function Get-Record {
Param ($Log)
    for ($i=1; $i -lt $Log.Count; $i++) { # ignore the header
        $Testcase = $Log[$i].split("`n")
        $Output = New-Object PSobject -Property @{
            Name = $Testcase[0]
            Data = $Testcase[3..($Testcase.count)]|?{!($_ -match "\[#TC#]")}
            }
        $Output|Add-Member -MemberType NoteProperty -Name "Error" -value $(if($Output.data -match "^.+?(\[#ERROR#]|\[#WARNING#])"){$true}else{$false})
        $Output
    }
} # End: Function Get-Record

之后我查看了$ Log获得后的值。最终得到一个包含3个字符串的数组。这一切都很好,但是如果你问我,你真正想要的是一个包含3个数组的数组。现在$ Log [0]是一个包含4行文字的字符串,你最好使用4个字符串的数组...所以让我们先走这条路。我修改了你的Get-Record来完成它。

Function Get-Record {
Param ($Log)
    for ($i=1; $i -lt $Log.Count; $i++) { # ignore the header
        $Testcase = $Log[$i].split("`n")

您会注意到使用正则表达式匹配在n which is the powershell NewLine character. Then I updated the object you created to exclude the [#TC#] which was used as a delimiter, and assigned it a variable instead of just outputting it. Once I had that $Output variable I tested it for [#ERROR#] and [#WARNING#]`上完成拆分,并为对象添加了新的Error属性,具体取决于如果发现错误。

        $Output = New-Object PSobject -Property @{
            Name = $Testcase[0]
            Data = $Testcase[3..($Testcase.count)]|?{!($_ -match "\[#TC#]")}
            }
        $Output|Add-Member -MemberType NoteProperty -Name "Error" -value $(if($Output.data -match "^.+?(\[#ERROR#]|\[#WARNING#])"){$true}else{$false})
        $Output
    }
} # End: Function Get-Record

然后我几乎按原样通过了其余部分,除了添加了我从示例文本中创建的日志的路径。

# Load the log into memory
$Log = Get-Log c:\temp\test.log
$Records = Get-Record -Log $Log
$Records # Added only to see the current progress. 
#} #End: Function Import-MyLog1
#
#clear
#Import-MyLog1

现在,如果你愿意的话,你可以通过从行首开始修剪空白来清理它,但这只是一个品味问题。但它在$ Records中为您提供了2个条目,每个条目都包含您想要的名称,数据行和布尔错误属性。