【问题标题】:How to get data for past hour, 6h, 24h from CSV log file with awk, sed or other?如何使用 awk、sed 或其他方式从 CSV 日志文件中获取过去一小时、6 小时、24 小时的数据?
【发布时间】:2020-06-07 11:33:20
【问题描述】:

我有一个以下格式的 csv 日志文件。我不太擅长 awk/sed。有人能告诉我如何提取过去一小时、6 小时和 24 小时的数据吗?

这是我的日志格式:

blabla,11:04:44,Alarm,121,TBD,TBD
blabla,11:04:50,Alarm,121,TBD,00:00:05
blabla,11:04:54,Warning,121,00:00:09,00:00:05
blabla,11:06:12,Alarm,125,TBD,TBD
blabla,11:06:42,Alarm,125,TBD,00:00:29
blabla,16:06:55,Warning,125,00:00:41,00:00:29
blabla,16:09:13,Alarm,125,TBD,TBD
blabla,16:10:32,Alarm,125,TBD,TBD
blabla,16:14:50,Alarm,125,TBD,TBD
blabla,16:15:00,Normal,125,00:00:10,TBD
blabla,16:15:03,Normal,125,00:00:10,00:00:13
blabla,20:04:08,Alarm,121,TBD,TBD
blabla,20:04:21,Normal,121,00:00:13,TBD
blabla,20:04:25,Normal,121,00:00:13,00:00:16
blabla,20:06:12,Alarm,125,TBD,TBD

所以假设现在的时间是 21:00:00,我需要过去一小时的数据,输出将是:

blabla,20:04:08,Alarm,121,TBD,TBD
blabla,20:04:21,Normal,121,00:00:13,TBD
blabla,20:04:25,Normal,121,00:00:13,00:00:16
blabla,20:06:12,Alarm,125,TBD,TBD

过去 6 小时的输出应该是:

blabla,16:06:55,Warning,125,00:00:41,00:00:29
blabla,16:09:13,Alarm,125,TBD,TBD
blabla,16:10:32,Alarm,125,TBD,TBD
blabla,16:14:50,Alarm,125,TBD,TBD
blabla,16:15:00,Normal,125,00:00:10,TBD
blabla,16:15:03,Normal,125,00:00:10,00:00:13
blabla,20:04:08,Alarm,121,TBD,TBD
blabla,20:04:21,Normal,121,00:00:13,TBD
blabla,20:04:25,Normal,121,00:00:13,00:00:16
blabla,20:06:12,Alarm,125,TBD,TBD

等等。

我试图自己想出一些东西,只是通过查看其他答案,但我似乎没有得到这些答案:

awk '$0>=from && $0<=to' from="$(date +"%H:%M:%S -d '1 hour ago'")" to="$(date +"%H:%M:%S")" logfile.csv (this actually produces error unexpected EOF while looking for matching)

sed -n "/^[^,]*,[^$(date --date='24 hours ago' '+%H:%M:%S'),],[^,]*,[^,]*,[^,]*,[^,]*/,\$p" logfile.csv

【问题讨论】:

  • 我们如何知道每个时间戳属于哪个日期?我的意思是如果现在是 21:00:00 并且文件中有 20:30:00 的时间戳,我们怎么知道这是今天( 1 小时前)的时间戳。跨度>
  • @EdMorton Ed,目标是只保留日志的最后 24 小时,并处理它并从日志开始后每秒重写一次,这样任何条目都不会超过 24 小时。我现在认为这是一个糟糕的日志设计(不是我的选择),我想我会添加另一个字段来存储每个日志条目自纪元开始以来的秒数。这应该更容易解析任何时间范围内的日志,您同意吗?
  • 是的,这样会更容易。顺便说一句,您的时间戳是 UTC 吗?如果他们是最好的。
  • 好的,太好了,我会试试的。不,时间戳是本地系统时间。该系统与网络完全隔离,所以我认为这应该是可以接受的......

标签: csv parsing awk sed date-arithmetic


【解决方案1】:

使用 Miller (https://github.com/johnkerl/miller) 并运行

mlr --csv -N put '$sourcetime=$2' \
then nest --explode --values --across-fields --nested-fs ":" -f 2 \
then put '$seconds=$2_1*3600+$2_2*60+$2_3' \
then filter '(21*3600-$seconds)<3600'  \
then cut -x -r -f '(_|sec)' input

你会有

+--------+--------+-----+----------+----------+------------+
| blabla | Alarm  | 121 | TBD      | TBD      | 20:04:08   |
| blabla | Normal | 121 | 00:00:13 | TBD      | 20:04:21   |
| blabla | Normal | 121 | 00:00:13 | 00:00:16 | 20:04:25   |
| blabla | Alarm  | 125 | TBD      | TBD      | 20:06:12   |
+--------+--------+-----+----------+----------+------------+
  • 我已将时间转换为秒 ($seconds=$2_1*3600+$2_2*60+$2_3);
  • 并从时间 21:00:00 开始过滤(秒为 21*3600),最后一小时的所有记录(秒为 3600),使用'(21*3600-$seconds)&lt;3600'

您可以根据需要更改过滤器参数

【讨论】:

    【解决方案2】:

    您的 AWK 尝试即将完成:

    $ awk  -F, '$2 >= from' from=$(date -d "6 hours ago" +%H:%M:%S) sample.txt
    
    blabla,20:04:08,Alarm,121,TBD,TBD
    blabla,20:04:21,Normal,121,00:00:13,TBD
    blabla,20:04:25,Normal,121,00:00:13,00:00:16
    blabla,20:06:12,Alarm,125,TBD,TBD
    

    您需要使用-F, 告诉awk 以, 分割。这利用了即使它们是字符串“20:04:08”>“20:00:00”。但是,对于其他格式,您可能需要做一些数学运算。

    我不认为sed 会起作用,它无法比较字符串,并且您可能不会在日志中找到完全匹配的内容。如果您知道文件中存在时间,那很简单:

    sed -n '/20:04:08/,$p' sample.txt
    blabla,20:04:08,Alarm,121,TBD,TBD
    blabla,20:04:21,Normal,121,00:00:13,TBD
    blabla,20:04:25,Normal,121,00:00:13,00:00:16
    blabla,20:06:12,Alarm,125,TBD,TBD
    

    【讨论】:

      猜你喜欢
      • 2022-09-23
      • 1970-01-01
      • 1970-01-01
      • 2021-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-17
      • 1970-01-01
      相关资源
      最近更新 更多