我有一个csv文件,如下所示:
datetime,nameval1,nameval2,nameval3,...,namevalx
2015/03/16 19:55:10,a,b,c,...,x
2015/03/16 19:30:30,a1,b1,c1,...,x1
2015/03/16 19:30:50,a2,b2,c2,...,x2
我需要修改日期,这是此csv文件中第二行开始的第一个值,以便将分钟四舍五入为00,15,30,45,60(如果分钟为60则小时需要增加1,分钟值返回00,如果这是第23天的最后一小时,那么此日需要增加1)。
我发现awk命令可能帮助我实现我想做的事情。我已经简化为基于分钟舍入值的简单测试 - 如果分钟调整值为60,那么我将$ 5更改回00.
awk 'BEGIN {FS="[,/ :]"; OFS=","} {
if ($1=="datetime")
{
print
}
else
{
min=(int(($5+15/2)/15))*15
if(min == 60)
$5="00"
date=$1 "/" $2 "/" $3 " " $4 ":" $5 ":" $6
$1=$2=$3=$4=$5=$6=""
print date $0
}
;}' ./file.csv
我遇到了很多问题:
1)这是我得到的一行结果的一个示例,我没有设法正确合并日期和/或我需要awk打印剩余的起始列$ 7:
2014/03/16 19:00:50,,,,,,a,b,c,...,x
2)我使用awk分割csv文件的方式并不完全是我需要的,因为文件中的其他变量可能包含/或空格。我需要仅使用逗号进行拆分,然后使用这3个字符之一[/:]进一步将日期时间拆分为其组件年/月/日/小时/分钟/秒。
3)我需要通过if语句来避免触及我在这里做的文件的第一行,如果awk也可以做得更简单我会使用
谢谢!
答案 0 :(得分:2)
令人高兴的是,您的日期格式需要很少的调整才能使用mktime
,所以使用GNU awk:
awk -F, 'BEGIN { OFS = FS } NR != 1 { gsub(/[/:]/, " ", $1); ts = mktime($1); ts = int((ts + 450) / 900) * 900; $1 = strftime("%Y/%m/%d %H:%M:%S", ts) } 1' filename
这是mktime
函数的核心,它将适当格式化的时间戳转换为自Epoch(1970-01-01 00:00:00 UTC)以来的秒数。有了这个数字,四舍五入到四分之一小时就很容易了,而且一旦发生这种情况,格式mktime
预期的格式是/
和:
替换为空格的时间戳。所以:
BEGIN { # In the beginning:
OFS = FS # set the output field separator to
# the same as the input field sep.
# so the output is delimited the
# same way as the input
}
NR != 1 { # Unless this is the first line
gsub(/[/:]/, " ", $1) # replace / and : in the first field
# with spaces
ts = mktime($1) # calculate seconds since Epoch
ts = int((ts + 450) / 900) * 900 # round to quarter hour
$1 = strftime("%Y/%m/%d %H:%M:%S", ts) # write back suitably formatted
# time stamp
}
1 # then print.
这里最大的警告是,大多数这些东西都是特定于GNU的,所以你需要使用awk的GNU风格来运行它。您的包管理员可能会将其称为gawk
。