使用一分钟间隔时间戳替换CSV文件中的列

时间:2016-10-03 12:12:01

标签: bash awk

我有一个带有时间戳和一些数据值的CSV文件:

 1455840000,76.357,899.500,326.717,8.000
 1455840060,76.490,899.650,326.150,8.000
 ...etc

但我想用新的时间戳值替换timestamp列。最后一行应该是当前时间,所有先前行应该比它之后的行早一分钟。

如何使用shell脚本执行此操作,例如的bash / AWK?

4 个答案:

答案 0 :(得分:1)

您可以使用tac撤消文件内容,执行操作,然后反转回原始序列:

tac file.txt | \
    awk 'BEGIN{FS=OFS=","} NR==1{"date +%s"|getline cur; $1=cur; print; next}; \
              {$1=cur-(60*(NR-1)); print}' | tac
  • 对于(反向)第一行,我们在epoch中获取当前时间戳,并将其保存在变量cur

  • 对于下一行,我们将每行减去60 * (line number - 1)秒以获得所需的时间

请注意,您可以想象时间计算可能不准确。

示例:

% cat ts.txt 
1455840000,76.357,899.500,326.717,8.000
1455840060,76.490,899.650,326.150,8.000
1455840000,76.357,899.500,326.717,8.000
1455840060,76.490,899.650,326.150,8.000

% tac ts.txt | awk 'BEGIN{FS=OFS=","} NR==1{"date +%s"|getline cur; $1=cur; print; next}; {$1=cur-(60*(NR-1)); print}' | tac
1475497096,76.357,899.500,326.717,8.000
1475497156,76.490,899.650,326.150,8.000
1475497216,76.357,899.500,326.717,8.000
1475497276,76.490,899.650,326.150,8.000

答案 1 :(得分:1)

这可能是你想要的:

$ cat file
1455840000,76.357,899.500,326.717,8.000
1455840060,76.490,899.650,326.150,8.000
1455840000,76.357,899.500,326.717,8.000
1455840060,76.490,899.650,326.150,8.000
1455840000,76.357,899.500,326.717,8.000
1455840060,76.490,899.650,326.150,8.000

使用GNU awk:

$ awk 'BEGIN{FS=OFS=","; now=systime()} NR>FNR{$1 = now - (NR-2*FNR)*60; print}' file file
1475504973,76.357,899.500,326.717,8.000
1475505033,76.490,899.650,326.150,8.000
1475505093,76.357,899.500,326.717,8.000
1475505153,76.490,899.650,326.150,8.000
1475505213,76.357,899.500,326.717,8.000
1475505273,76.490,899.650,326.150,8.000

其他问题:

$ awk -v now=$(date +'%s') 'BEGIN{FS=OFS=","} NR>FNR{$1 = now - (NR-2*FNR)*60; print}' file file
1475504973,76.357,899.500,326.717,8.000
1475505033,76.490,899.650,326.150,8.000
1475505093,76.357,899.500,326.717,8.000
1475505153,76.490,899.650,326.150,8.000
1475505213,76.357,899.500,326.717,8.000
1475505273,76.490,899.650,326.150,8.000

答案 2 :(得分:0)

我将如何做到这一点:

tac inputFile | awk -v ts="$(date +%s)" -v OFS=, -F, '{ $4 = strftime("%c", ts - NR * 60) ; print $0 }' | tac

tac反转输入文件,以便我们可以从唯一已知值(当前日期)计算日期。我们处理完每一行后,我们会将其还原。

awk' -v标记使我们能够使用变量,因此我们让bash计算当前时间戳并将其传递给awk as一个unix时间戳(自1970年1月1日起的秒数)。

awk' -F标志指定列分隔符。

然后在每一行,最后一列被先前读取的每一行的给定时间戳减去60秒替换,我们以strftime的人类可读格式显示。

示例:

$ cat inputFile
a,b,c,d
a1,b1,c1,d1
a2,b2,c2,d2

$ tac inputFile | awk -v ts="$(date +%s)" -v OFS=, -F, '{ $4 = strftime("%c", ts - NR * 60) ; print $0 }' | tac
a,b,c,lun.  3 oct. 2016 15:32:29
a1,b1,c1,lun.  3 oct. 2016 15:33:29
a2,b2,c2,lun.  3 oct. 2016 15:34:29

答案 3 :(得分:0)

此Gnu awk脚本首先获取当前时间戳(纪元时间),在第一次迭代后记住文件的NR,并在第二次迭代时更新时间戳:

$ awk -F, 'BEGIN{ts=strftime("%s")} NR==FNR{nr=NR; next}{$1=ts-(nr-FNR)*60} 1' file file
1455840000 76.357 899.500 326.717 8.000
1455840060 76.490 899.650 326.150 8.000

与所有awks兼容 - 包括上面的Gnu awk-replace BEGIN{}

BEGIN{"date +'%s'"|getline ts}