如何在特定时间段内grep日志文件

时间:2014-07-31 01:55:11

标签: linux bash awk grep

好的,所以我有日志文件,我想在特定范围内搜索。这些范围全天都不同。下面是一个日志文件,这是我可以告诉你的唯一一件事,抱歉工作的东西。如果重要的话,我正在使用cat命令。

工作示例:cat /dir/dir/dir/2014-07-30.txt | grep *someword* | cut -d',' -f1,4,3,7

2014-07-30 19:17:34.542 ;; (p=0,siso=0)

以上为我提供了我需要的信息以及时间戳,但显示了所有时间范围,这就是我想要纠正的内容。假设我在第一列中只需要18到20的范围。

实际 - > 2014-07-30 19:17:34.542 ;; (p=0,siso=0)

只有我想要的范围 - > [18-20]:00:00.000 ;; (p=0,siso=0)

我并不担心00,因为它们可以是任何数字。

谢谢你的期待。从你的例子中可以看出,我没有太多使用脚本的方式,但是非常感谢任何帮助。

我已经包含了一个日志文件,冒号和逗号就是它们应该存在的位置。

2014-07-30 14:33:19.259 ;; (p=0,ser=0,siso=0) IN ### Word:Numbers=00000,word=None something goes here and here (something here andhere:here also here:2222),codeword=8,codeword=0,Noideanumbers=00000000,something=something, ;;

6 个答案:

答案 0 :(得分:2)

使用awk

logsearch() {
    grep "$3" "$4" | awk -v start="$1" -v end="$2" '{split($2, a, /:/)} (a[1] >= start) && (a[1] <= end)'
}

# logsearch <START> <END> <PATTERN> <FILE>
logsearch 18 20 '*someword*' /dir/dir/dir/2014-07-30.txt

或仅使用awk(可能是不同的模式引用要求):

logsearch2 ()
{
    awk -v start="$1" -v end="$2" -v pat="$3" '($0 ~ pat) {split($2, a, /:/)} ($0 ~ pat) && (a[1] >= start) && (a[1] <= end)' "$4"
}

答案 1 :(得分:0)

您可以将结果再次传递给grep

cat /dir/dir/dir/2014-07-30.txt | grep someword | cut -d',' -f1,4,3,7 \
    | grep '^\d\d\d\d-\d\d-\d\d \(1[89]\|20\)'

答案 2 :(得分:0)

我没有看到原始输入数据,我猜测你正在做什么。

这会给你一些类似于你想要的结果吗?

 awk -F, '/someword/ && $4 ~ /^(18|19|20)/{printf "%s %s %s %s\n", $1,$4,$3,$7}' /dir/dir/dir/2014-07-30.txt

那就是说:一些样本数据通常会有很长的路要走!

EDIT1:

根据您在评论和原始帖子中添加的输入行,以下awk语句会执行您要求的内容:

awk '/something/ && $2 ~ /^(18|19|20)/{printf "%s %s %s %s\n", $1,$2,$3,$4} /path/to/your/input_file

答案 3 :(得分:0)

这是一个非常有趣的问题。纯粹的BASH解决方案在您识别出响应感兴趣的日期/时间范围的条目后,为您处理或处理条目提供了相当大的灵活性。 BASH中最简单的方法就是从epoch开始以秒为单位获取开始时间和停止时间,然后测试每个日志条目以确定它是否在该范围内然后 - 对日志条目执行某些操作。涉及的基本逻辑相对较短。可以通过将width作为参数4来设置日志中date_time字段的宽度。根据需要设置默认值dwidth(当前为15以匹配syslog和journalctl格式。唯一必需的参数是日志文件名。没有指定开始/停止时间,它将找到所有条目:

## set filename, set start time and stop time (in seconds since epoch) 
#  and time_field width (number of chars that make up date in log entry)
lfname=${1}
test -n "$2" && starttm=`date --date "$2" +%s` || starttm=0
test -n "$3" && stoptm=`date --date "$3" +%s`  ||  stoptm=${3:-`date --date "Jan 01 2037 00:01:00" +%s`}
dwidth=${4:-15}

## read each line from the log file and act on only those with
#  date_time between starttm and stoptm (inclusive)
while IFS=$'\n' read line || test -n "$line"; do

    test "${line:0:1}" != - || continue           # exclude journalctl first line
    logtm=`date --date "${line:0:$dwidth}" +%s`   # get logtime from entry in seconds since epoch

    if test $logtm -ge $starttm && test $logtm -le $stoptm ; then
        echo "logtm: ${line:0:$dwidth} => $logtm"
    fi

done < "${lfname}"

工作示例:

#!/bin/bash

## log date format      len
#   journalctl          15
#   syslog              15
#   your log example    23

function usage {
    test -n "$1" && printf "\n Error: %s\n" "$1"
    printf "\n  usage  : %s logfile ['start datetime' 'stop datetime' tmfield_width]\n\n" "${0//*\//}"
    printf "  example: ./date-time-diff.sh syslog \"Jul 31 00:15:02\" \"Jul 31 00:18:30\"\n\n"
    exit 1
}

## test for required input & respond to help
test -n "$1" || usage "insufficient input."
test "$1" = "-h" || test "$1" = "--help" && usage

## set filename, set start time and stop time (in seconds since epoch) 
#  and time_field width (number of chars that make up date in log entry)
lfname=${1}
test -n "$2" && starttm=`date --date "$2" +%s` || starttm=0
test -n "$3" && stoptm=`date --date "$3" +%s`  ||  stoptm=${3:-`date --date "Jan 01 2037 00:01:00" +%s`}
dwidth=${4:-15}

## read each line from the log file and act on only those with
#  date_time between starttm and stoptm (inclusive)
while IFS=$'\n' read line || test -n "$line"; do

    test "${line:0:1}" != - || continue           # exclude journalctl first line
    logtm=`date --date "${line:0:$dwidth}" +%s`   # get logtime from entry in seconds since epoch

    if test $logtm -ge $starttm && test $logtm -le $stoptm ; then
        echo "logtm: ${line:0:$dwidth} => $logtm"
    fi

done < "${lfname}"

exit 0

<强>用法:

$ ./date-time-diff.sh -h

  usage  : date-time-diff.sh logfile ['start datetime' 'stop datetime' tmfield_width]

  example: ./date-time-diff.sh syslog "Jul 31 00:15:02" "Jul 31 00:18:30"

记得引用你的starttm和stoptm字符串。在7月31日00:12:58和7月31日00:21:10之间使用日志文件中的20个条目进行测试。

测试输出:

$ ./date-time-diff.sh jc.log "Jul 31 00:15:02" "Jul 31 00:18:30"
logtm: Jul 31 00:15:02 => 1406783702
logtm: Jul 31 00:15:10 => 1406783710
logtm: Jul 31 00:15:11 => 1406783711
logtm: Jul 31 00:15:11 => 1406783711
logtm: Jul 31 00:15:11 => 1406783711
logtm: Jul 31 00:15:11 => 1406783711
logtm: Jul 31 00:18:30 => 1406783910

根据您的需要,另一个解决方案可能符合您的需求,但如果您需要能够处理或操作匹配的日志条目,则很难击败BASH脚本。

答案 4 :(得分:-1)

我没有足够的声誉来评论,但是因为minopret建议一次做一次grep。

以下是获得18-20范围的解决方案之一:

grep ' 20: \| 17:\| 18:' filename.txt

答案 5 :(得分:-1)

我找到了我正在寻找的答案中的答案:

cat /dir/dir/dir/2014-07-30.txt | grep *someword* | cut -d',' -f1,4,3,7 | egrep '[^ ]+ (2[0-2]):[0-9]'

以下命令从切割中获取了我需要的所有信息,以及我需要的 someword 的greps,并且使用egrep我可以搜索我需要的时间。