Bash 在awk中处理时间并将输出转换为csv文件中的新列的最佳方法是什么?

Bash 在awk中处理时间并将输出转换为csv文件中的新列的最佳方法是什么?,bash,awk,Bash,Awk,假设有一个简单的csv文件: date,miles,time,min 2016-01-01,5.15,0:21:10,0:03:30 2016-01-03,15.30,1:10:00,0:03:45 2016-02-02,08.37,0:31:24,0:03:22 假设我想再添加两列,其中H:M:S时间转换为十进制数,其中1.0等于一小时。如何使用awk有效地实现这一点?目前,我将此文件的一个字段通过管道传输到另一个awk命令,在该命令中,我使用:作为字段分隔符,使用一些算术运算(例如,字段2

假设有一个简单的csv文件:

date,miles,time,min
2016-01-01,5.15,0:21:10,0:03:30
2016-01-03,15.30,1:10:00,0:03:45
2016-02-02,08.37,0:31:24,0:03:22

假设我想再添加两列,其中H:M:S时间转换为十进制数,其中1.0等于一小时。如何使用awk有效地实现这一点?目前,我将此文件的一个字段通过管道传输到另一个awk命令,在该命令中,我使用
作为字段分隔符,使用一些算术运算(例如,字段2除以60)获得十进制数,将结果保存到一个文件,然后使用
粘贴
组合原始文件和派生文件。有更简单的方法,不是吗

由于您没有向我们展示您的预期输出,这可能是您想要的,也可能不是您想要的:

$ cat tst.awk
BEGIN { FS=OFS="," }
{
    if (NR==1) {
        tdec = "time_dec"
        mdec = "min_dec"
    }
    else {
        split($3,a,/:/); tdec = a[1] + a[2]/60 + a[3]/3600
        split($4,a,/:/); mdec = a[1] + a[2]/60 + a[3]/3600
    }
    print $0, tdec, mdec
}

$ awk -f tst.awk file
date,miles,time,min,time_dec,min_dec
2016-01-01,5.15,0:21:10,0:03:30,0.352778,0.0583333
2016-01-03,15.30,1:10:00,0:03:45,1.16667,0.0625
2016-02-02,08.37,0:31:24,0:03:22,0.523333,0.0561111

但是,如果这不完全是您想要的,希望您能得到这个想法。

因为您没有向我们展示您的预期输出,这可能是您想要的,也可能不是您想要的:

$ cat tst.awk
BEGIN { FS=OFS="," }
{
    if (NR==1) {
        tdec = "time_dec"
        mdec = "min_dec"
    }
    else {
        split($3,a,/:/); tdec = a[1] + a[2]/60 + a[3]/3600
        split($4,a,/:/); mdec = a[1] + a[2]/60 + a[3]/3600
    }
    print $0, tdec, mdec
}

$ awk -f tst.awk file
date,miles,time,min,time_dec,min_dec
2016-01-01,5.15,0:21:10,0:03:30,0.352778,0.0583333
2016-01-03,15.30,1:10:00,0:03:45,1.16667,0.0625
2016-02-02,08.37,0:31:24,0:03:22,0.523333,0.0561111

但如果这不是你想要的,希望你能得到这个想法。

是的。使用
split
功能将时间字段拆分为数组。甚至不需要海绵(如果你的意思是在打印任何东西之前将整个文件的结果读取到内存中)。第一步:
awk-F',“{OFS=”,“print$1,$2,$3,$4,“foo”}文件
你能更具体一点吗,@triplee?我看不出
split
如何应用于基于某个分隔符拆分字段。@cfye14类似这样的内容:
split($3,a,“:”);打印[1]+(a[2]+a[3]/60)/60
where
FS=“,”
如果Awk的
split
功能的文档似乎不适用,我认为任何东西都不会。是的。使用
split
功能将时间字段拆分为数组。甚至不需要海绵(如果你的意思是在打印任何东西之前将整个文件的结果读取到内存中)。第一步:
awk-F',“{OFS=”,“print$1,$2,$3,$4,“foo”}文件
你能更具体一点吗,@triplee?我看不出
split
如何应用于基于某个分隔符拆分字段。@cfye14类似这样的内容:
split($3,a,“:”);打印一个[1]+(a[2]+a[3]/60)/60
where
FS=“,”
如果Awk的
split
函数的文档似乎不适用,我认为没有任何东西会适用。通过几个Awk问题,我发现创建一个.Awk文件是很常见的,然后针对要处理的文件运行它。这只是更干净的首选项,还是随机的首选项?由于Windows噩梦般的引用规则,强烈建议所有在Windows下运行的脚本都使用此选项,只建议在UNIX中使用更大的脚本,否则这是首选项。唯一的功能区别是文件中的awk脚本可以使用硬编码的单引号(
)字符,因为它不是单引号分隔的。当调用awk时,我经常在回答中使用它来清楚地将awk脚本与变量和/或文件或其他参数的设置分开。明白了,这很有意义。通过几个awk问题,我发现创建一个.awk文件,然后针对要处理的文件运行该文件是很常见的。这只是更干净的首选项,还是随机的首选项?由于Windows噩梦般的引用规则,强烈建议所有在Windows下运行的脚本都使用此选项,只建议在UNIX中使用更大的脚本,否则这是首选项。唯一的功能区别是文件中的awk脚本可以使用硬编码的单引号(
)字符,因为它不是单引号分隔的。我在回答中经常使用它,以便在调用awk时将awk脚本与变量和/或文件或其他参数的设置清楚地分开。明白了,这很有意义。