我有以下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
,字段分隔符是-
或(空格)或
:
,然后我打印第一行标题,对于第一行之后的所有行我使用时间函数,mktime
将YYYY 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
mmin
为7:30
AM,单位为秒。mmax
是晚上7:30秒。dt
是输入的日期-时间,所有-
和:
都用空格替换(这是mktime
的输入格式)。s
是使用mktime
将dt
转换为Epoch以来的秒数。dt0
和s0
与dt
和s
相同,但在00:00:00
。d
为从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