在Powershell中更改解析器的输出结果

时间:2018-07-10 15:23:46

标签: performance function powershell parsing

因此,我有一个解析器,该解析器遍历两个不同的日志(两个.csv文件),并根据我选择的正则表达式代码检查某些行。

此文件从文件名的开头(1234-randomfile.csv)抓取IDNumber,然后将文件位置添加到变量($ Validate),然后基于正则表达式,将文件添加到某些变量($ Scriptdone, $ Updatedone,$ Failed),然后开始检查以查看它们是否具有它们。

我正在尝试使其成为一行一行,因为我解析的文件具有相同的IDNumbers。例如:

当前输出:

1234 Script Completed
1234 Update Completed

我要如何输出:

1234 Script Completed Update Completed

无论如何,谢谢您的协助!

function Get-MR4RES {
[CmdletBinding()]
param (
    [Parameter(Position = 0,
        Mandatory = $True)]
    [ValidateNotNullorEmpty()]
    [ValidateScript( {Test-Path -Path $_ -PathType 'Any'})]
    [String]
    $Files,

    [Parameter(Position = 1,
        Mandatory = $false)]
    [String]
    $CSVPath) # End Param

begin {

    # Setting Global Variables
    $Scriptcompletedsuccess = '.+Script\scompleted\ssuccessfully.+' # 3:44:15 End function called, Script completed successfully at  3:44:15 on Tue 07/03/2018
    $Updatecomplete = '\w+\s+\:\s\[\d+\:\d+\:\d+\]\s+\w+\scomplete' # STATUS  : [03:43:07]   Update complete
    $FailedValidaton = '.+check\sfail.+'
    $Fail1 = 'Validation Failed'
    $Fail2 = 'Failed'
    $Good1 = 'Script completed'
    $Good2 = 'Update completed'
    $array = @('IDNumber, Results')
    $counter = 0
    $FileList = (Get-ChildItem -Path $Files -File -Filter "*.log").FullName
    $Done = ''

} # End begin

process {

    # Do the following code in all the files in the filelist
    foreach ($File in $fileList) {

        # Test files variables to ensure is directory to ensure progress bar will be operational and needed
        if ((Get-Item $Files) -is [System.IO.DirectoryInfo]) {

            # Counts once per each file variable in filelist variable
            $counter++

            # Progress bar indicates the name of the current file and calculates percent based on current count verses total files in $filelist
            Write-Progress -Activity 'Analyzing Files' -CurrentOperation $File -PercentComplete (($counter / $FileList.count) * 100)

        }

        # Calculates ID number based on filename, file name is -filtered in beginning to only contain properly named files
        $IDNumber = [System.IO.Path]::GetFileName("$File").split('-')[0]

        # Puts file into Variable to be IF Else
        $Validate = Get-Content -Path $File

        $Scriptdone = $Validate | Where-Object {$_ -match $Scriptcompletedsuccess}
        $Updatedone = $Validate | where-object {$_ -match $Updatecomplete}
        $Failed = $Validate | Where-Object {$_ -match $FailedValidaton}

        # Check if the file HAS a FAILED validation
        if($Failed){

            # Creates an array of the data from each file that failed
            $array += -join ("$IDNumber",', ',"$Fail1")
        }
        Elseif($Scriptdone){
            $Done = $Good1

            # Creates an array of the data from each file that script completed
            $array += -join ("$IDNumber",', ',"$Done")

        } # if the parser found "Update complete"
        Elseif($Updatedone){
            $Done = $Good2

            # Creates an array of the data from each file that update is done
            $array += -join ("$IDNumber",', ',"$Done")

        } # End of Successful
        Else{
            # Creates an array of the data from each file that failed
            $array += -join ("$IDNumber",', ',"$Fail2")
        }

    } # End of foreach

} # End process section

End {

    # If CSVPath is used in get-command 
    if ($PSBoundParameters.ContainsKey('CSVPath')) {

        # Pipe the array data to a CSV
        Add-Content -Path $CSVPath -Value $array -Encoding ascii

    }

    # If no CSVPath is used in get-command
    else {

        # Out-put to console
        Write-Output $array

    } # End of else

} # End of the End

} # End of function

1 个答案:

答案 0 :(得分:0)

如果要将新消息追加到现有输出,则必须告诉PowerShell应该将新信息添加到哪个条目。由于我认为操作字符串不是很直观,因此建议您使用一个对象。

首先,您必须定义数据结构:

// Before ForEach
$array = @()
$properties = @{'ID'="";
            'Results'=""}
// In ForEach
$object = New-Object –TypeName PSObject –Prop $properties
$object.ID = $IDNumber

接下来,在您的if中,您可以设置值(也可以按照@LotPings的建议使用Switch进行设置,但为了简单起见,请将其保留不变):

$object.Results = $Done // or $Fail or $Fail2

然后,您应该首先检查带有$ID的条目是否已经存在,如果是,则添加新结果。如果否,则只需将新元素添加到数组中。这样的事情应该起作用:

$line = $array | Where-Object ID -eq $object.id
if ($line) {
  $line.Results += " $($object.Results)"
}
else {
  $array += $object
}

当然,这还需要更改数据输出方式(例如,使用Export-Csv):

$array | Export-Csv $CSVPath -Append -NoTypeInformation