从多个日志文件中提取给定开始和结束时间之间的记录

时间:2018-06-03 15:10:45

标签: bash shell awk sed grep

我们的日志文件格式为百万条记录:

xyz,xyz, YYYY-MM-DD HH:MM:SS ,....,

我们将以格式获取starttime和endtime: YYYYMMDDHHMMSS 作为shellscript的输入。 我们想从时间戳在starttime和endtime之间的所有日志文件中提取记录。

日志中的单个记录:abc,def,ghi, 2018-06-03 11:00:00 ,...,xyz

包装脚本:xyz.sh' 20180603112000' ' 20180604120000'

预期输出:给定两个时间戳之间的所有记录。

1 个答案:

答案 0 :(得分:0)

#!/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

这是一个包含所有匹配$到

的行的解决方案
sed -n "/$from/,\$p" file | sed "/$to/{/$to/{N};q}"

新部件的说明:Q将在autoprint之前退出, 但由于我使用p进行打印,我必须确保Q在/$to/Q;p之前触发, 或者使用单独的sed调用来获得更容易理解的解决方案。

第二个解决方案只是自动打印,直到遇到$ /$to/。 然后,它会将匹配$的每个后续行追加到patspace /$to/{N}。 最终q打印patspace并退出sed。