Home > Software engineering >  Replace string and find value in column in Batch file
Replace string and find value in column in Batch file

Time:04-26

I have file like below, I need to find out that if any employee is "absent OR unknown" or late more than 1 min in both time column.

Col1          col2        col3     HH MM SS        HH MM SS 
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 am successful to remove ":" but not sure how to put if condition piping echo

(for /f "delims=" %%i in (%files%) do (
        set "line=%%i"
        setlocal enabledelayedexpansion
        set "line=!line::= !" 
      echo(!line!  
       endlocal
    )) 

trying to get output like

George is more than 1 hr and 2 min late
Linda is absent 

Any help is Greatly appreciated.

CodePudding user response:

@ECHO Off
SETLOCAL ENABLEDELAYEDEXPANSION
SET "filename1=q72007068.txt"

(
FOR /f "skip=1delims=" %%e IN (%filename1%) DO (
 SET "reason="
 FOR %%y IN (%%e) DO (
  FOR %%o IN (absent unknown) DO IF %%o==%%y SET "reason=%%o"
  FOR /f "tokens=1-3delims=:" %%u IN ("%%y") DO (
   IF "%%w"=="" (
    SET "person=%%y" 
    ) ELSE (
     SET /a late=1%%u%%v%%w
     IF NOT DEFINED reason IF !late! gtr 1000100 SET "reason=late %%u:%%v:%%w"
    )
  )
 )
 IF DEFINED reason ECHO !person! is !reason!
)
)

GOTO :EOF

%%e receives each full line, skipping the first, from the file.

reason is used as a flag to record the reason the report line is being generated - if it is generated.

%%y receives each element of the line in turn.

If an element is exactly absent or unknown, set reason to that value.

Attempt to tokenise the element into %%u..%%w using : as a delimiter.

If %%w is not set, then this is not a time element, so person will be set to the element value and hence will contain the element before the first time element, which is the person's name.

If %%w is set, form hh:mm:ss as 1hhmmss which is a decimal number which does not have a leading 0. Compare that against 1000100 which is 1 minute calculated on the same basis. if greater, then set reason to "late the actual time-late.

If, after processing all of the elements, reason has been set then produce a report line detailing the person and reason.

I'll leave the formatting of the time as an exercise for those interested.

CodePudding user response:

This may be what you're trying to do:

$ cat tst.awk
NR == 1 {
    next
}
$2 ~ /^(absent|unknown)$/ {
    printf "%s is %s\n", $3, $2
    next
}
{
    for ( i=4; i<=5; i   ) {
        split($i,t,":")
        hrs[i]  = t[1]
        mins[i] = t[2]
        tot_mins[i]  = t[1]*60   t[2]   t[3]/60
    }
}
(tot_mins[4] > 1) && (tot_mins[5] > 1) {
    printf "%s is more than %d hours and %d mins late\n", $3, hrs[4], mins[4]
}

$ awk -f tst.awk file
George is more than 1 hours and 2 mins late
Linda is absent
James is unknown

If that's not exactly what you need I expect it's obvious how to tweak it to do whatever you do want.

  • Related