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