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

时间:2015-04-19 01:08:48

标签: bash awk

我有一个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也可以做得更简单我会使用

谢谢!

1 个答案:

答案 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