bash - 从多个日志文件中提取给定开始时间和结束时间之间的记录
问题描述
我们有日志文件,其格式将包含数百万条记录:
xyz,xyz, YYYY-MM-DD HH:MM:SS ,....,
我们将得到格式为:YYYYMMDDHHMMSS的开始时间和结束时间作为 shellscript 的输入。我们想从时间戳在开始时间和结束时间之间的所有日志文件中提取记录。
日志中的单条记录:abc,def,ghi, 2018-06-03 11:00:00 ,...,xyz
包装脚本:xyz.sh '20180603112000' '20180604120000'
预期输出:给定两个时间戳之间的所有记录。
解决方案
#!/bin/sh
d4="([0-9]{4})"
d2="([0-9]{2})"
pattern="$d4$d2$d2$d2$d2$d2"
replace='\1-\2-\3 \4:\5:\6'
from=$(echo "$1" | sed -r "s/$pattern/$replace/")
to=$(echo "$2" | sed -r "s/$pattern/$replace/")
sed -n "/$from/,\$p;/$to/q" file
在简单的英语中,它包括 $from 的第一个匹配项和匹配 $to 的第一行。
具体来说,脚本首先将输入转换为文件中预期出现的时间戳。然后 sed 默认不打印 (-n) 迭代文件,但打印从第一行到最后一行 ($) 的所有内容,但是如果遇到 $to,sed 将退出。
虽然这个解决方案并不完美。它的工作假设是每一秒至少包含一个日志行。或者至少搜索的秒数。通常,您不需要按秒提取日志行,我建议按小时或分钟提取块。当然,除非你有大量的日志行,在这种情况下,我认为这个假设成立。其次,它假设日志行中的数据不包含任何时间戳。如果数据本身包含时间戳,则此功能可能会中断。
更新: 我不太喜欢我给出的解决方案,因为它只打印与 $to 匹配的第一行。它很容易制作,但可能不是你想要的。这是一个在匹配 $to 的第一行之前停止的解决方案:
sed -n "/$from/,\$p" file | sed "/$to/Q"
你可以通过一个 sed 调用来做到这一点,但它有点难以理解:
sed -n "/$from/,\${/$to/Q;p}" file
这是一个包含所有匹配 $to 的行的解决方案
sed -n "/$from/,\$p" file | sed "/$to/{/$to/{N};q}"
新部分的说明: Q 将在自动打印之前退出,但由于我使用 p 进行打印,我必须确保 Q 在 p 之前触发/$to/Q;p
,或者使用单独的 sed 调用以获得更易于理解的解决方案。
第二种解决方案只是自动打印,直到遇到 $to /$to/
。然后它将匹配 $to 的每个后续行附加到 patspace /$to/{N}
。最后q
打印 patspace 并退出 sed。
推荐阅读
- python - 每 5 秒在 Tableau Server 上自动刷新 Tableau Live 仪表板
- jquery - Windows 7 上选择的库中未捕获的类型错误
- java - 对于长度 < 255 个字符且相对速度足够快的字符串,哪个是具有最小冲突的哈希函数?
- c - 如何在visual studio c 中打印■?
- javascript - IE 11 无法从 Angular 中的字节数组创建文件对象
- php - 通过 file_get_contents 发送帖子数据,客户端/浏览器可读的帖子数据?
- email - 将密码直接发送到恢复电子邮件而不是密码重置链接
- java - Intellij 将多个 Java 类声明到一个文件中导致奇怪的 UI
- javascript - 如何在js中解构嵌套对象
- postgresql - 创建在我结束事务时自行删除的临时表