从logfile中提取最后10分钟

use*_*671 9 bash datetime date logfiles

试图找到一个简单的方法来观看最近的事件(从不到10分钟),我试过这个:

awk "/^$(date --date="-10 min" "+%b %_d %H:%M")/{p++} p" /root/test.txt
Run Code Online (Sandbox Code Playgroud)

但它没有按预期工作......

日志文件格式如下:

Dec 18 09:48:54 Blah
Dec 18 09:54:47 blah bla
Dec 18 09:55:33 sds
Dec 18 09:55:38 sds
Dec 18 09:57:58 sa
Dec 18 09:58:10 And so on...
Run Code Online (Sandbox Code Playgroud)

小智 10

这是一个很好的工具范围是从-10到现在你想要的任何一个

sed -n "/^$(date --date='10 minutes ago' '+%b %_d %H:%M')/,\$p" /var/log/blaaaa
Run Code Online (Sandbox Code Playgroud)

  • 这很酷。即使日志很大,也超快。如果我想要 xxx.xxx.xxx.xxx - - [25/Oct/2014:22:42:45 +0800] “GET,如何编辑 sed 命令?我试过 date --date='1 分钟前' '+[%d/%b/%Y:%H:%M' 但它没有用 (2认同)

F. *_*uri 7

这是的一个(常见)工作!:

简单高效:

perl -MDate::Parse -ne 'print if/^(.{15})\s/&&str2time($1)>time-600' /path/log
Run Code Online (Sandbox Code Playgroud)

该版本打印最后10分钟的情况下,高达现在,通过使用time功能.

您可以使用以下方法测试:

sudo cat /var/log/syslog |
  perl -MDate::Parse -ne '
    print if /^(\S+\s+\d+\s+\d+:\d+:\d+)\s/ && str2time($1) > time-600'
Run Code Online (Sandbox Code Playgroud)

请注意,第一个表示仅使用每行15个字符,而第二个构造使用更详细的正则表达式.

作为perl脚本: last10m.pl

#!/usr/bin/perl -wn

use strict;
use Date::Parse;
print if /^(\S+\s+\d+\s+\d+:\d+:\d+)\s/ && str2time($1) > time-600
Run Code Online (Sandbox Code Playgroud)

严格:从logfile中提取最后10分钟

含义与当前时间无关,但与logfile中的最后一个条目相关:

检索期末有两种方法:

date -r logfile +%s
tail -n1 logfile | perl -MDate::Parse -nE 'say str2time($1) if /^(.{15})/'
Run Code Online (Sandbox Code Playgroud)

在逻辑上,日志文件的最后修改时间必须是最后一次输入的时间.

所以命令可以变成:

perl -MDate::Parse -ne 'print if/^(.{15})\s/&&str2time($1)>'$(
    date -r logfile +%s)
Run Code Online (Sandbox Code Playgroud)

或者您可以最后一个条目作为参考:

perl -MDate::Parse -E 'open IN,"<".$ARGV[0];seek IN,-200,2;while (<IN>) {
    $ref=str2time($1) if /^(\S+\s+\d+\s+\d+:\d+:\d+)/;};seek IN,0,0;
    while (<IN>) {print if /^(.{15})\s/&&str2time($1)>$ref-600}' logfile
Run Code Online (Sandbox Code Playgroud)

第二个版本看起来更强,但只能访问文件一次.

作为perl脚本,这可能看起来像:

#!/usr/bin/perl -w

use strict;
use Date::Parse;
my $ref;                 # The only variable I will use in this.

open IN,"<".$ARGV[0];    # Open (READ) file submited as 1st argument
seek IN,-200,2;          # Jump to 200 character before end of logfile. (This
                         # could not suffice if log file hold very log lines! )
while (<IN>) {           # Until end of logfile...
    $ref=str2time($1) if /^(\S+\s+\d+\s+\d+:\d+:\d+)/;
};                       # store time into $ref variable.
seek IN,0,0;             # Jump back to the begin of file
while (<IN>) {
    print if /^(.{15})\s/&&str2time($1)>$ref-600;
}
Run Code Online (Sandbox Code Playgroud)

但如果你真的想用

有一个非常快速的纯bash脚本:

警告:这使用最近的bashisms,需要$BASH_VERSION4.2或更高.

#!/bin/bash

declare -A month

for i in {1..12};do
    LANG=C printf -v var "%(%b)T" $(((i-1)*31*86400))
    month[$var]=$i
  done

printf -v now "%(%s)T" -1
printf -v ref "%(%m%d%H%M%S)T" $((now-600))

while read line;do
    printf -v crt "%02d%02d%02d%02d%02d" ${month[${line:0:3}]} \
        $((10#${line:4:2})) $((10#${line:7:2})) $((10#${line:10:2})) \
        $((10#${line:13:2}))
    # echo " $crt < $ref ??"   # Uncomment this line to print each test
    [ $crt -gt $ref ] && break
done
cat
Run Code Online (Sandbox Code Playgroud)

存储此脚本并运行:

cat >last10min.sh
chmod +x last10min.sh
sudo cat /var/log/syslog | ./last10min.sh
Run Code Online (Sandbox Code Playgroud)

严格:从logfile中提取最后10分钟

只需替换第10行,但您必须将文件名放在脚本中,而不是将其用作过滤器:

#!/bin/bash

declare -A month

for i in {1..12};do
    LANG=C printf -v var "%(%b)T" $(((i-1)*31*86400))
    month[$var]=$i
  done

read now < <(date -d "$(tail -n1 $1|head -c 15)" +%s)
printf -v ref "%(%m%d%H%M%S)T" $((now-600))

export -A month

{
    while read line;do
        printf -v crt "%02d%02d%02d%02d%02d" ${month[${line:0:3}]} \
            $((10#${line:4:2})) $((10#${line:7:2})) $((10#${line:10:2})) \
            $((10#${line:13:2}))
        [ $crt -gt $ref ] && break
    done
    cat
} <$1
Run Code Online (Sandbox Code Playgroud)


Sto*_*ica 5

您可以使用简单的字符串比较来匹配日期范围,例如:

d1=$(date --date="-10 min" "+%b %_d %H:%M")
d2=$(date "+%b %_d %H:%M")
while read line; do
    [[ $line > $d1 && $line < $d2 || $line =~ $d2 ]] && echo $line
done
Run Code Online (Sandbox Code Playgroud)

例如,如果d1='Dec 18 10:19'd2='Dec 18 10:27'然后输出将是:

Dec 18 10:19:16
Dec 18 10:19:23
Dec 18 10:21:03
Dec 18 10:22:54
Dec 18 10:27:32
Run Code Online (Sandbox Code Playgroud)

awk根据需要使用:

awk -v d1="$d1" -v d2="$d2" '$0 > d1 && $0 < d2 || $0 ~ d2'
Run Code Online (Sandbox Code Playgroud)