Allan Teoh
Allan Teoh

Reputation: 3

How to read array and combine with unique ID?

I'm writing a PowerShell script to read from logs and generate a report, the logs have a prefix format like below example:

If JobType ID equal to 1 then it will have format "JobType UserName UserID"  
If JobType ID equal to 2 then it will have format "JobType JobID UserID Action Result"

Sample:

1,Allan,12334
1,Kath,12335  
2,001,12334,Send,Success
2,002,12335,Recv,Success
2,003,12334,Recv,Fail
1,Grace,12336
2,004,12336,Send,Success

My end result should be:

Job 001, Allan send successfully
Job 002, Kath receive successfully
Job 003, Allan receive failed

I'm able to split the array for variable, but I'm not sure how to combine the UserID in different line and generate the result?

Sample script:

$Logs = Get-content logs.txt
Foreach ($line In $Logs) {
  if ($line[0] -eq "1") {
    $JobType, $Username, $UserID = $line -split ','

    Write-host $JobType
    Write-host $Username
    Write-host $UserID
  } elseif ($line[0] -eq "2") {
    $JobType, $JobID, $UserID, $Action, $Result  = $line -split ',' 

    Write-host $JobType
    Write-host $JobID 
    Write-host $UserID  
    Write-host $Action  
    Write-host $Result
  }  
}

Upvotes: 0

Views: 142

Answers (3)

Manuel Batsching
Manuel Batsching

Reputation: 3606

If I get your question right, you are asking, how to join different lines from your logs.txt over a corresponding UserID. You could do this by building a hashtable that maps user IDs to usernames:

$Logs = Get-Content .\logs.txt

$userMap = @{}
$jobLog = @()
foreach ($line In $Logs)
{
    if ($line[0] -eq '1')
    {
        $null, $Username, $UserID = $line -split ','
        $userMap[$UserID] = $Username
    }

    elseif ($line[0] -eq '2')
    {
        $jobLog += $line
    }
    # Do whatever is appropriate for logs with different IDs
}

Now you can generate your desired result from the remaining lines by substitution. You may also want to use an extra hastable, to substitute keywords like 'Recv':

$keywordMap = @{ 
    'Send' = 'send' 
    'Recv' = 'receive'
    'Success' = 'successfully'
    'Fail' = 'failed' 
}
foreach ($line in $jobLog)
{
    $null, $JobID, $UserID, $Action, $Result = $line -split ','
    Write-Output ('Job {0}, {1} {2} {3}' -f $JobID,
        $userMap[$UserID], $keywordMap[$Action], $keywordMap[$Result])
}

Upvotes: 0

Ansgar Wiechers
Ansgar Wiechers

Reputation: 200463

Use the format operator (-f) for building output strings like that, and use a switch statement to distinguish between the cases:

$JobType, $data = $line -split ',', 2
switch ($JobType) {
  1 {
    $Username, $UserID = $data -split ','
    '{0} {1} {2}' -f $JobType, $Username, $UserID
  }
  2 {
    $JobID, $UserID, $Action, $Result  = $data -split ',' 
    '{0} {1} {2} {3} {4}' -f $JobType, $JobID, $UserID, $Action, $Result
  }
  default { "Unknown job type: $JobType" }
}

Upvotes: 1

Avshalom
Avshalom

Reputation: 8889

You can use this instead...

$Logs = Get-content logs.txt 

$Type1 = $Logs | ? {$_ -match "^1"}
$Type2 = $Logs | ? {$_ -match "^2"}

$T1Header = "JobType","UserName","UserID"
$T2Header = "JobType","JobID","UserID","Action","Result"

$CSVT1 = ConvertFrom-Csv $Type1 -Delimiter "," -Header $T1Header
$CSVT2 = ConvertFrom-Csv $Type2 -Delimiter "," -Header $T2Header

It will create for you 2 CSV files each with required header

Upvotes: 0

Related Questions