Bash:如何替换csv文件中的日期,并将分钟四舍五入为4个值之一



我有一个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,那么小时需要增加一,分钟值又回到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也可以做得更简单,我会使用

谢谢!

令人高兴的是,您的日期格式只需要很少的调整就可以使用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

最新更新