Ami*_*mit 25 grep sed awk text-processing
我想提取两个时间戳之间的所有日志。有些行可能没有时间戳,但我也想要这些行。简而言之,我希望每一行都在两个时间戳下。我的日志结构如下所示:
[2014-04-07 23:59:58] CheckForCallAction [ERROR] Exception caught in +CheckForCallAction :: null
--Checking user--
Post
[2014-04-08 00:00:03] MobileAppRequestFilter [DEBUG] Action requested checkforcall
Run Code Online (Sandbox Code Playgroud)
假设我想提取2014-04-07 23:00
和之间的所有内容2014-04-08 02:00
。
请注意日志中可能没有开始时间戳或结束时间戳,但我想要这两个时间戳之间的每一行。
max*_*zig 20
您可以awk
为此使用:
$ awk -F'[]]|[[]' \
'$0 ~ /^\[/ && $2 >= "2014-04-07 23:00" { p=1 }
$0 ~ /^\[/ && $2 >= "2014-04-08 02:00" { p=0 }
p { print $0 }' log
Run Code Online (Sandbox Code Playgroud)
在哪里:
-F
使用正则表达式指定字符[
和]
作为字段分隔符$0
引用完整的一行$2
引用日期字段p
用作保护实际打印的布尔变量$0 ~ /regex/
如果正则表达式匹配则为真 $0
>=
用于按字典顺序比较字符串(相当于 eg strcmp()
)上面的命令行实现了右开时间间隔匹配。要获得闭区间语义,只需增加您正确的日期,例如:
$ awk -F'[]]|[[]' \
'$0 ~ /^\[/ && $2 >= "2014-04-07 23:00" { p=1 }
$0 ~ /^\[/ && $2 >= "2014-04-08 02:00:01" { p=0 }
p { print $0 }' log
Run Code Online (Sandbox Code Playgroud)
如果您想以另一种格式匹配时间戳,则必须修改$0 ~ /^\[/
子表达式。请注意,它曾经从打印开/关逻辑中忽略没有任何时间戳的行。
例如,对于像YYYY-MM-DD HH24:MI:SS
(不带[]
大括号)这样的时间戳格式,您可以像这样修改命令:
$ awk \
'$0 ~ /^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-2][0-9]:[0-5][0-9]:[0-5][0-9]/
{
if ($1" "$2 >= "2014-04-07 23:00") p=1;
if ($1" "$2 >= "2014-04-08 02:00:01") p=0;
}
p { print $0 }' log
Run Code Online (Sandbox Code Playgroud)
(请注意,字段分隔符也已更改 - 默认为空白/非空白转换)
cpu*_*smv 12
dategrep
在https://github.com/mdom/dategrep查看
描述:
dategrep 在指定的输入文件中搜索匹配日期范围的行并将它们打印到标准输出。
如果 dategrep 在可搜索文件上工作,它可以进行二进制搜索以非常有效地找到要打印的第一行和最后一行。如果文件名参数只是一个连字符,则 dategrep 也可以从 stdin 读取,但在这种情况下,它必须解析每一行,这会变慢。
用法示例:
dategrep --start "12:00" --end "12:15" --format "%b %d %H:%M:%S" syslog
dategrep --end "12:15" --format "%b %d %H:%M:%S" syslog
dategrep --last-minutes 5 --format "%b %d %H:%M:%S" syslog
dategrep --last-minutes 5 --format rsyslog syslog
cat syslog | dategrep --end "12:15" -
Run Code Online (Sandbox Code Playgroud)
尽管此限制可能使这不适合您的确切问题:
目前 dategrep 会在找到不可解析的行后立即终止。在未来的版本中,这将是可配置的。
归档时间: |
|
查看次数: |
86501 次 |
最近记录: |