2016-10-03 19 views
0

文件我有一个CSV带时间戳和一些数据值文件:在CSV更换色谱柱用一分钟的间隔时间戳记

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

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

如何使用shell脚本执行此操作庆典/ AWK?

+0

我们如何知道'start'和'结束'时间戳?我们从哪里开始和结束? – Inian

+0

@Inian结束时间戳是当前时间。然后以相反的顺序在一分钟内递减到文件的开始递减。该文件可以是任何长度,因此除了计算行数之外,我们不知道开始时间戳。 – mtmacdonald

+0

当你说_然后以相反的顺序迭代到file_的开始时,什么定义_start_? – Inian

回答

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 
  • 对于(反转)第一行,我们得到当前时间戳的时代,并将其保存在一个变量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 
+0

根据我对Aaron的回答的评论,在Q中没有迹象表明OP正在运行可能包含'tac'的操作系统,所以我提到了一些替代方案。 – ghoti

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作为UNIX时间戳(秒数自01/01/1970)。

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 
+0

如果您使用的操作系统不包含'tac'(如FreeBSD或OS X或Solaris或AIX等),请检查您的'tail'命令是否有'-r'选项。如果失败了,你可以用'awk'{L [i ++] = $ 0}得到类似的结果(假设你有内存来保存文件)END {for(j = i-1; j> = 0;)print L [J - ]}“'。 – ghoti

0

这羚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 

For compatibility with all awks — including Gnu awk — replace BEGIN{} block above with

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

+1

'strftime()'函数是GNU awk的一部分,但不是我知道的其他变体。 – ghoti

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 

与其他awks:

$ 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 
相关问题