获取日期并转换为工作日



我有以下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

我需要在两个字段中输出工作日和轮班时间,如果hh:mm在7:30AM到7:30PM之间,则应打印为上午,其余将打印为晚上。

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

我试着用以下命令工作日和面临困难转变列请帮

date --date="$dates" +%A

使用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

生产

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

从你的输入。

它从日期中裁剪秒,使用GNU awk特定的函数mktime()strftime()从时间中获取工作日,最后将小时部分与所需的范围进行比较,以确定是早晨还是晚上。

获取日期并转换为工作日

我将使用GNUAWK来完成这个任务,让file.txt上下文为

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

然后

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

给输出

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

解释:首先我通知GNUAWK,字段分隔符是-(空格)或:,然后我打印第一行标题,对于第一行之后的所有行我使用时间函数,mktimeYYYY MM DD HH MM SS转换为时间戳(自epoch开始的秒数),然后我使用strftime将该变量转换为字符串,%A表示完整的工作日名称。

(在gawk 4.2.1中测试)

使用awk(使用GNUawk测试):

$ awk '
BEGIN {
sep = sprintf("%41s", " ")
gsub(/ /, "-", sep);
printf("%-19s | %-9s | %-10sn%sn", "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 | %sn", $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

mmin7:30AM,单位为秒。mmax是晚上7:30秒。dt是输入的日期-时间,所有-:都用空格替换(这是mktime的输入格式)。s是使用mktimedt转换为Epoch以来的秒数。dt0s0dts相同,但在00:00:00d为从00:00:00到现在的秒数。剩下的很简单。

awk '
NR==1{
printf "%-16s | %-9s | %sn", "Date","Weekday","Shift"; next   
}
{
"date -d "" $0 "" "+%d-%m-%Y %H:%M | %A"" | getline d
gsub(/:/, "", $2); t=int($2)
printf "%-28s | %sn", 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

支持文本、字符串和csv,ruby是我的首选项目:

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|%*sn"
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 

打印:

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

使用system()比使用getline要轻得多:

{m,g}awk '($++NF=substr("SunMonTueWedThuFriSat",1+3 * 
system("exit 140 gdate -d42"($_)" UTC-442 +%w 140"), 3))  
($++NF=substr("MorngNight",6^($2~/^(2|0[0-6]|07:[0-2]|19:[^0-2])/),5))
2022-06-09 22:30:20 Thu Night
2022-06-10 15:55:21 Fri Morng
2022-06-11 00:34:05 Sat Night
2022-06-11 19:51:52 Sat Night
2022-06-13 11:34:10 Mon Morng
2022-06-15 03:59:54 Wed Night
2022-06-18 16:13:20 Sat Morng
2022-06-19 00:24:21 Sun Night
2022-06-19 00:25:36 Sun Night
2022-06-19 00:25:36 Sun Night
2022-06-19 00:25:49 Sun Night

最新更新