Home > Blockchain >  Parse column values line by line and pass to ifelse
Parse column values line by line and pass to ifelse

Time:04-30

I have code in shell script, but can't figure out how to parse line by line in column.

If person is absent I want to send email. if person is late than hour then send warning email. if person is extremely late in column 5 like more than 4 hours then send alert email.

Below is the file


sales       Present     George     01:02:00        04:05:00
sales       absent      Linda      00:00:03        00:00:00
Marketing   unknown     James      00:00:00        00:00:00

I reproduced like this in shell script.

late=`cat $file | grep "latetime" | tr -s " " | cut -f3 -d " " | awk -F: '{print $1*3600 $2*60 $3}'` status=`cat $file | grep Status | tr -s " " | cut -d " " -f 8

I tried to write the below code, but no success. Can you please help here?

$contents = Get-Content status.txt
foreach($line in $contents) {
$s = $line -split ' '
#$s = $line
  $department = $s[0]
  $status = $s[1]
  $name = $s[2]
  # string in Total min 
  $1stlatetime = $s[$s*3600 $s*60 $s] 
  #string in Total min 
  $2ndlatetime = $s[$s*3600 $s*60 $s]
  if ($status = "absent")
  {
  email = "$name is absent from $department"
  ElseIf ($1stlatetime -ge "5") 
 email = "$name is absent from $department is late than $1stlatetime"
  Elseif (2ndlatetime -ge "10")
 email = "$name is absent from $department is Extremely late than $2stlatetime"
 else 
 Echo "all are on Time"
} ```

CodePudding user response:

The codes not bad and you are pretty close. The biggest issue is that when you split each line in the foreach loop, it includes blank lines. Just need to split it into a temp var, and do a .foreach to get rid of the blank lines ($null).

The next thing, is calculating the time. Need to go into s[3],s[4] and split those on ':'. After that you can calculate the time but you have to cast the split s[3]/s[4] to an int.

$contents = Get-Content -Path ./status.txt 

foreach ($line in $contents) {
    $tempS = $line.Split(' ')

    $s = $tempS.ForEach({if($_){$_}})

    $temp1st = ($s[3].Split(':'))
    $1stlatetime = ([int]$temp1st[0]*3600) ([int]$temp1st[1]*60) [int]$temp1st[2]

    $temp2nd = ($s[4].Split(':'))
    $2ndlatetime = ([int]$temp2nd[0]*3600) ([int]$temp2nd[1]*60) [int]$temp2nd[2]


    $email = $null
    if ($s[1] -contains 'absent') {

        if($1stlatetime -gt 5){
            $email = "$($s[2]) is absent from $($s[0]) is late; more than $1stlatetime"
        }
        elseif ($2ndlatetime -ge 10) {
            $email = "$($s[2]) is absent from $($s[0]) is Extremely late; more than $2ndlatetime"
        }
        else {
            $email = "$($s[2]) is absent from $($s[0])"
        }
    }

    Write-Host "This is S: $s`n"
    Write-Host "This is 1st: $1stlatetime`n"
    Write-Host "This is 2nd: $2ndlatetime`n"
    Write-Host "This is EMAIL: $email"

}

Here's the output received:

This is S: sales Present George 01:02:00 04:05:00

This is 1st: 3720

This is 2nd: 14700

This is EMAIL: This is S: sales absent Linda 00:00:03 00:00:00

This is 1st: 3

This is 2nd: 0

This is EMAIL: Linda is absent from sales This is S: Marketing unknown James 00:00:00 00:00:00

This is 1st: 0

This is 2nd: 0

This is EMAIL:

CodePudding user response:

From your question, it is oimpossible to say what is used to separate the field values..
If this file uses spaces between the fields, you can read the data in like this:

$data = (Get-Content -Path 'status.txt' -Raw) -replace '\s{2,}(?<!\r?\n)', ',' | 
         ConvertFrom-Csv -Header Department, Status, Name, FirstTimeLate, SecondTimeLate

If however, the delimiter used is a TAB character, things wil be somewhat simpler:

$data = Import-Csv -Path 'status.txt' -Delimiter "`t" -Header Department, Status, Name, FirstTimeLate, SecondTimeLate

Now that you have the data as array on objects, you can loop through the elements and collect your email strings in variable $result:

$result = $data | ForEach-Object {
    $lateFirst  = [TimeSpan]::Parse($_.FirstTimeLate).TotalMinutes
    $lateSecond = [TimeSpan]::Parse($_.SecondTimeLate).TotalHours

    if ($_.Status -eq 'absent') {
        '{0} is absent from {1}'-f $_.Name, $_.Department
    }
    elseif ($lateSecond -gt 4) {
       '{0} from {1} is EXTREMELY late by {2:F2} hours..' -f $_.Name, $_.Department, $lateSecond
    }
    elseif ($lateFirst -gt 5) {
        '{0} from {1} is late by {2:F2} minutes' -f $_.Name, $_.Department, $lateFirst
    }
}

# if $result has 1 or more elements, join them with a newline for the email body
$email = if (@($result).Count) {
    $result -join [Environment]::NewLine
}
else { 
    'Everyone is on Time'
}

# send the email

Using your example file, $email will contain

George from sales is EXTREMELY late by 4.08 hours..
Linda is absent from sales
  • Related