搜索日期范围

搜索日期范围

我正在尝试设置一个 BASH 脚本,该脚本允许我输入日期范围,确认范围,然后实际搜索该范围。但每次我尝试时,由于某种原因,它似乎都只是空的。我遵循基于这里虽然有点老了,但希望其中有些部分是准确的。我知道代码很粗糙,可以清理一下,但我在这方面还是新手,任何帮助我都会非常感激。

#!/bin/bash

date_1=''
date_2=''

read -p "Please Enter the Beggining Time. Exp. Aug 1 00:00:01 " date_1;

read -p "Please Enter the Beggining Time. Exp. Aug 1 00:00:01 " date_2;

while :
 do
    read -p "Is this Date correct? @date_1" choice
    case ${choice} in
        y|ye|yes) break;;
        n|no) echo "Try again"; exec $0;;
    esac
done
while :
 do
    read -p "Is this Date correct? @date_2" choice
    case ${choice} in
        y|ye|yes) break;;
        n|no) echo "Try again"; exec $0;;
    esac
done

echo $date_1 , $date_2
find /srv/log/mail -mtime $(date +%s -d"$date_1") -mtime $(date +%s -d"$date_2")

答案1

1.最佳解决方案:Python

执行bash此类任务可能有点太复杂,因为它没有足够的工具来实现此目的。当然可以做到,但需要付出很大努力。因此,我们需要一套工具,让我们能够以更简单的方式解析日志文件。Python 通过datetime模块提供了这样的工具集。

下面给出的 Python 脚本在命令行上接受 3 个参数:单引号或双引号的开始时间戳、单引号或双引号的结束时间戳以及要读取的文件。时间戳的格式应与“星期一 HH:MM:SS”格式一致。

#!/usr/bin/env python
import datetime as dt
import sys

def convert_to_seconds(timestring):
    year = str(dt.date.today().year)
    dtobj = dt.datetime.strptime( year + ' ' + timestring , '%Y %b %d %H:%M:%S' )
    return int(dtobj.strftime('%s'))

beginning = convert_to_seconds(sys.argv[1])
ending = convert_to_seconds(sys.argv[2])

with open(sys.argv[3]) as log:
    for line in log:
        logstamp = " ".join(line.strip().split()[0:3])
        s_logstamp = convert_to_seconds(logstamp)
        if s_logstamp < beginning: continue
        if s_logstamp >= beginning and s_logstamp <= ending:
            print(line.strip())
            sys.stdout.flush()
        if s_logstamp > ending: break

测试运行于/var/log/syslog

$ ./read_log_range.py 'Feb 8 13:57:00'  'Feb 8 14:00:00' /var/log/syslog                              
Feb  8 13:57:59 eagle gnome-session[28631]: (nm-applet:28825): GdkPixbuf-CRITICAL **: gdk_pixbuf_composite: assertion 'dest_x >= 0 && dest_x + dest_width <= dest->width' failed
Feb  8 13:59:55 eagle org.gtk.vfs.Daemon[28480]: ** (process:2259): WARNING **: Couldn't create directory monitor on smb://x-gnome-default-workgroup/. Error: Operation not supported by backend
Feb  8 13:59:59 eagle gnome-session[28631]: (nm-applet:28825): GdkPixbuf-CRITICAL **: gdk_pixbuf_composite: assertion 'dest_x >= 0 && dest_x + dest_width <= dest->width' failed

2. Bash

当然,也可以在 中这样做bash,使用dateawk实用程序来提取时间戳和转换。下面是bash相同 Python 脚本的实现。

#!/usr/bin/env bash
#set -x
str_to_seconds(){
    date -d"$1" +%s
}

main(){
    local date1=$1
    local date2=$2
    local logfile=$3

    local s_date1=$(str_to_seconds "$date1")
    local s_date2=$(str_to_seconds "$date2")

    while IFS= read -r line;
    do
        timestamp=$(awk '{print $1,$2,$3}' <<< "$line")
        s_timestamp=$(str_to_seconds "$timestamp")
        [ $s_timestamp -lt $s_date1  ] && continue
        if [ $s_timestamp -ge $s_date1  ] && [ $s_timestamp -le $s_date2  ]
        then
            printf "%s\n" "$line"
        fi
        [ $s_timestamp -gt $s_date2  ] && break

    done < "$logfile"
}

main "$@"

3. 两种方法的比较

当然,bash版本需要更长的时间。 Shell 不适用于处理大量数据,例如日志。例如,在我的带有 SSD 和双核处理器的机器上,shell 花费了大量时间来读取近 13,000 行文件:

$ time ./read_log_range.sh 'Feb 8 13:56:00'  'Feb 8 14:00:00' '/var/log/syslog' &> /dev/null          
    0m39.18s real     0m02.48s user     0m02.68s system

$ wc -l /var/log/syslog 
12878 /var/log/syslog

即使对语句进行了几次优化也if无济于事。将其与 Python 替代方案进行比较:

$ time ./read_log_range.py 'Feb 8 13:56:00'  'Feb 8 14:00:00' '/var/log/syslog' &> /dev/null          
    0m00.60s real     0m00.53s user     0m00.07s system

$ wc -l /var/log/syslog                                                                               
12878 /var/log/syslog

如你所见,python 比它的bash对手快了大约 65 倍。

相关内容