处理带有时间戳的文本文件并每秒输出最后一行

处理带有时间戳的文本文件并每秒输出最后一行

我有一个 csv 文件,其中包含纳秒分辨率的时间戳,格式"YYYY-MM-DDTHH:MM:SS.fffffffffZ"为后跟一些数据

2021-04-26T09:30:04.786235633Z,102 
2021-04-26T09:30:04.786235633Z,524 
2021-04-26T09:30:04.786235633Z,566 
2021-04-26T09:30:04.791050014Z,391 
2021-04-26T09:30:09.882687589Z,922 
2021-04-26T09:30:09.886405549Z,744 
2021-04-26T09:30:09.886405549Z,702 
2021-04-26T09:30:14.986237837Z,436 
2021-04-26T09:30:14.986237837Z,636 
2021-04-26T09:30:14.986298532Z,353 
2021-04-26T09:30:14.986298532Z,445 
2021-04-26T09:30:14.986298532Z,785 
2021-04-26T09:30:14.986298532Z,917 
2021-04-26T09:30:20.086229659Z,195 
2021-04-26T09:30:20.086229659Z,228 
2021-04-26T09:30:20.086229659Z,486 
2021-04-26T09:30:20.086229659Z,41 
2021-04-26T09:30:20.086229659Z,421 
2021-04-26T09:30:20.090214746Z,386 
2021-04-26T09:30:25.186477272Z,678 
2021-04-26T09:30:25.186477272Z,198 
2021-04-26T09:30:25.190264104Z,459 
2021-04-26T09:30:25.190460283Z,123 
2021-04-26T09:30:25.190460283Z,318 
2021-04-26T09:30:26.442994013Z,200 

我想以这样的方式处理它,只有每秒最后一行是输出:

2021-04-26T09:30:04.791050014Z,391 
2021-04-26T09:30:09.886405549Z,702 
2021-04-26T09:30:14.986298532Z,917 
2021-04-26T09:30:20.090214746Z,386 
2021-04-26T09:30:25.190460283Z,318 
2021-04-26T09:30:26.442994013Z,200 

是否可以使用 awk 或类似的工具来做到这一点?

答案1

使用 GNU sort,你可以这样做:

<file.csv sort -r | sort -suk1,1.19

sort按时间倒序排列,然后按时间顺序对结果进行排序,但仅考虑前 19 个字符以忽略亚秒,并使用(用于唯一)选择第一个(由于先前的和稳定的-u,这将是较新的一个)顺序)具有相同 19 个字符密钥的那些。sort-s

除了 之外-k1,1.19,您还可以-t. -k1,1选择第一行之前的行部分.作为排序键。

如果输入文件已经按时间顺序排列,您可以将第一个替换sorttac(或tail -r在某些系统上)。

答案2

是的,这是可能的:跟踪最后一秒和相应的行,每当秒发生变化时,输出记住的行:

awk -F. 'NR > 1 && lastsec != $1 { print lastline }
         { lastsec = $1; lastline = $0 }
         END { if (NR) print }'

答案3

使用Python结合模块groupby中的方法itertools

分组是在时间(第零字段)上完成的,并且从该组中,最后一个元素是该组的目标行。

python3 -c 'import itertools as it, sys
fs,rs = ofs,ors = ".","\n"
with open(sys.argv[1]) as f:
  print(*[list(group)[-1].rstrip(rs) for key,group in it.groupby(f,lambda x: x.split(fs)[0]) if key],sep=ors)
' file

流编辑器 sed 可以这样处理:

sed -Ee '
  $!N
  /^([^.]+\.).*\n\1/!P
  D
' file

本质上,我们比较两行连续的内容,特别是它们的第一个点分隔字段。只有当它们不匹配时,我们才会打印。

答案4

sed 'N;/^\([^.]*\.\).*\n\1/D;P;D' file

命令 D 中的主要功能。它不仅从字符串对中删除第一个字符串,而且还使用缓冲区中剩余的字符串重新启动脚本开头的操作。

相关内容