我有一个带有时间戳和一些数据值的CSV文件:
1455840000,76.357,899.500,326.717,8.000
1455840060,76.490,899.650,326.150,8.000
...etc
但我想用新的时间戳值替换timestamp列。最后一行应该是当前时间,所有先前行应该比它之后的行早一分钟。
如何使用shell脚本执行此操作,例如的bash / AWK?
答案 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}