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