i have data below in csv
Date
2022-06-09 22:30:20
2022-06-10 15:55:21
2022-06-11 00:34:05
2022-06-11 19:51:52
2022-06-13 11:34:10
2022-06-15 03:59:54
2022-06-18 16:13:20
2022-06-19 00:24:21
2022-06-19 00:25:36
2022-06-19 00:25:36
2022-06-19 00:25:49
i required output in 2 fields as weekday and shift time, if hh:mm is between 7:30AM to 7:30PM it should be print as morning, remaining will be print as Night.
date | Weekday | Shift
--------------------------------------------------------------
09-06-2022 22:30 | Thursday | Night
10-06-2022 15:55 | Friday | Morning
11-06-2022 00:34 | Saturday | Night
11-06-2022 19:51 | Saturday | Night
13-06-2022 11:34 | Monday | Morning
15-06-2022 03:59 | Wednesday | Night
18-06-2022 16:13 | Saturday | Morning
19-06-2022 00:24 | Sunday | Night
19-06-2022 00:25 | Sunday | Night
19-06-2022 00:25 | Sunday | Night
19-06-2022 00:25 | Sunday | Night
I tried with below command to get weekdays and facing difficulties in shift column please help
date --date="$dates" %A
CodePudding user response:
Using GNU awk:
gawk 'function dayofweek(time) {
gsub(/[:-]/, " ", time)
return strftime("%A", mktime(time));
}
BEGIN { OFS="," }
NR == 1 { print "Date", "Weekday", "Shift"; next }
{
print substr($0, 0, length($0) - 3), dayofweek($0), $2 >= "07:30:00" && $2 <= "19:30:00" ? "Morning" : "Night"
}' input.csv
produces
Date,Weekday,Shift
2022-06-09 22:30,Thursday,Night
2022-06-10 15:55,Friday,Morning
2022-06-11 00:34,Saturday,Night
2022-06-11 19:51,Saturday,Night
2022-06-13 11:34,Monday,Morning
2022-06-15 03:59,Wednesday,Night
2022-06-18 16:13,Saturday,Morning
2022-06-19 00:24,Sunday,Night
2022-06-19 00:25,Sunday,Night
2022-06-19 00:25,Sunday,Night
2022-06-19 00:25,Sunday,Night
from your input.
It trims the seconds from the date, uses GNU awk specific functions mktime()
and strftime()
to get the weekday from the time, and finally just compares the hours portion to the desired range to see if it's morning or night.
CodePudding user response:
fetch date and covert into weekday
I would use GNU AWK
for this task following way, let file.txt
context be
Date
2022-06-09 22:30:20
2022-06-10 15:55:21
2022-06-11 00:34:05
2022-06-11 19:51:52
2022-06-13 11:34:10
2022-06-15 03:59:54
2022-06-18 16:13:20
2022-06-19 00:24:21
2022-06-19 00:25:36
2022-06-19 00:25:36
2022-06-19 00:25:49
then
awk 'BEGIN{FS="-| |:"}NR==1{print "Date","Weekday"}NR>1{t=mktime($1 " " $2 " " $3 " " $4 " " $5 " " $6);print $0,strftime("%A",t)}' file.txt
gives output
Date Weekday
2022-06-09 22:30:20 Thursday
2022-06-10 15:55:21 Friday
2022-06-11 00:34:05 Saturday
2022-06-11 19:51:52 Saturday
2022-06-13 11:34:10 Monday
2022-06-15 03:59:54 Wednesday
2022-06-18 16:13:20 Saturday
2022-06-19 00:24:21 Sunday
2022-06-19 00:25:36 Sunday
2022-06-19 00:25:36 Sunday
2022-06-19 00:25:49 Sunday
Explanation: firstly I inform GNU AWK
that field separator is -
or
(space) or :
, then for 1st line I print header, for all lines after 1st I use Time Functions, mktime
converts string like YYYY MM DD HH MM SS
into timestamp (number of seconds since start of epoch), then I use strftime
to convert said variable into string, %A
denotes full weekday name.
(tested in gawk 4.2.1)
CodePudding user response:
With awk
(tested with GNU awk
):
$ awk '
BEGIN {
sep = sprintf("As", " ")
gsub(/ /, "-", sep);
printf("%-19s | %-9s | %-10s\n%s\n", "Day", "Weekday", "Shift", sep)
mmin = 7 * 3600 30 * 60
mmax = 19 * 3600 30 * 60
}
NR > 1 {
dt = $0
gsub(/-|:/, " ", dt)
s = mktime(dt)
dt0 = $1 " 00 00 00"
gsub(/-/, " ", dt0)
s0 = mktime(dt0)
d = s - s0
shift = (d > mmin && d < mmax) ? "Morning" : "Night"
printf("%-19s | %-9s | %s\n", $0, strftime("%A", s), shift)
}' file
Day | Weekday | Shift
-----------------------------------------
2022-06-09 22:30:20 | Thursday | Night
2022-06-10 15:55:21 | Friday | Morning
2022-06-11 00:34:05 | Saturday | Night
2022-06-11 19:51:52 | Saturday | Night
2022-06-13 11:34:10 | Monday | Morning
2022-06-15 03:59:54 | Wednesday | Night
2022-06-18 16:13:20 | Saturday | Morning
2022-06-19 00:24:21 | Sunday | Night
2022-06-19 00:25:36 | Sunday | Night
2022-06-19 00:25:36 | Sunday | Night
2022-06-19 00:25:49 | Sunday | Night
mmin
is 7:30
AM in seconds. mmax
is 7:30 PM in seconds. dt
is the input date - time with all -
and :
replaced by a space (this is the input format of mktime
). s
is dt
converted to seconds since Epoch using mktime
. dt0
and s0
are the same as dt
and s
but at 00:00:00
. d
is the time in seconds since 00:00:00
. The rest is straightforward.
CodePudding user response:
awk '
NR==1{
printf "%-16s | %-9s | %s\n", "Date","Weekday","Shift"; next
}
{
"date -d \"" $0 "\" \" %d-%m-%Y %H:%M | %A\"" | getline d
gsub(/:/, "", $2); t=int($2)
printf "%-28s | %s\n", d ,(t > 73000 && t < 193000) ? "Morning" : "Night"
}' file.csv
Date | Weekday | Shift
09-06-2022 22:30 | Thursday | Night
10-06-2022 15:55 | Friday | Morning
11-06-2022 00:34 | Saturday | Night
11-06-2022 19:51 | Saturday | Night
13-06-2022 11:34 | Monday | Morning
15-06-2022 03:59 | Wednesday | Night
18-06-2022 16:13 | Saturday | Morning
19-06-2022 00:24 | Sunday | Night
19-06-2022 00:25 | Sunday | Night
19-06-2022 00:25 | Sunday | Night
19-06-2022 00:25 | Sunday | Night
CodePudding user response:
With text and string and csv support, ruby
is my go to for such projects:
ruby -r csv -e '
options={ :headers=>true, :converters=>:date_time}
def d_or_n(dt)
t=dt.strftime( "%H%M%S%N" )
st=DateTime.new(2000,1,1,7,30).strftime( "%H%M%S%N" )
et=DateTime.new(2000,1,1,19,30).strftime( "%H%M%S%N" )
t >= st && t <= et ? "Day" : "Night"
end
cols=[18,12,7]
fmt="%*s|%*s|%*s\n"
printf(fmt,cols[0],"Date".center(cols[0]),
cols[1],"Weekday".center(cols[1]), cols[2], "Shift".center(cols[2]))
printf("-"*(cols.sum 2) "\n")
inp=CSV.parse($<.read, **options).to_a
inp[1..].each{|r| printf(fmt, cols[0], r[0].strftime("%d-%m-%Y %R "),
cols[1], r[0].strftime("%A "),
cols[2], d_or_n(r[0])) }
' dates.csv
Prints:
Date | Weekday | Shift
---------------------------------------
09-06-2022 22:30 | Thursday | Night
10-06-2022 15:55 | Friday | Day
11-06-2022 00:34 | Saturday | Night
11-06-2022 19:51 | Saturday | Night
13-06-2022 11:34 | Monday | Day
15-06-2022 03:59 | Wednesday | Night
18-06-2022 16:13 | Saturday | Day
19-06-2022 00:24 | Sunday | Night
19-06-2022 00:25 | Sunday | Night
19-06-2022 00:25 | Sunday | Night
19-06-2022 00:25 | Sunday | Night