Shell 如何从最近10分钟的日志文件中获取具有特定字符串的行

Shell 如何从最近10分钟的日志文件中获取具有特定字符串的行,shell,awk,sed,grep,sh,Shell,Awk,Sed,Grep,Sh,尝试了其他解决方案,但没有给出正确的解决方案我的时间格式是[Thu Aug 20 09:28:51 2020]。最接近的是这个 awk -vDate=`date -d'now-2 hours' +[%a %b %d %H:%M:%S %Y]` '$4 > Date {print Date, $0}' $input 我的日志文件是这样的 [Thu Aug 20 09:10:51 2020] [error] vendor [Thu Aug 20 09:23:51 2020] [err

尝试了其他解决方案,但没有给出正确的解决方案我的时间格式是[Thu Aug 20 09:28:51 2020]。最接近的是这个

  awk -vDate=`date -d'now-2 hours' +[%a %b %d %H:%M:%S %Y]` '$4 > Date {print Date, $0}' $input
我的日志文件是这样的

 [Thu Aug 20 09:10:51 2020] [error] vendor
 [Thu Aug 20 09:23:51 2020] [error] vendor
 [Thu Aug 20 09:25:51 2020] [error] vendor
 [Thu Aug 20 09:27:51 2020] [error] vendor
 [Thu Aug 20 09:28:51 2020] [error] dad
我想要从当前时间[Thu Aug 20 09:28:51 2020]到最后10分钟的结果

  [Thu Aug 20 09:23:51 2020] [error] vendor
 [Thu Aug 20 09:25:51 2020] [error] vendor
 [Thu Aug 20 09:27:51 2020] [error] vendor
 [Thu Aug 20 09:28:51 2020] [error] dad

我试着直接使用grep,但我不知道为什么,但是grep没有采用这种日期格式,并且给出了一些错误的输出,所以我做了一些变通

#!/bin/bash
input="/home/babin/Desktop/code2"
count=0

dateyear=$(date +'%Y')
month=$(date +'%b')
day=$(date +'%a')

#do loop for 10 mins from now
for (( i = 0; i <=9; i++ )) ; do
     if grep $(date +%R -d "-$i  min") $input | grep -i "error" | grep -wi "$month" | grep -wi "$year" | grep -wi "$day"
     then
        currentcount=$(grep $(date +%R -d "-$i  min") $input | grep -wi "70007" | grep -wi "$month" | grep -wi "$year" | grep -wic "$day")
     else
        currentcount=0
        echo "not found"
     fi
      count=$(( $count + $currentcount )) 
done
    echo "$count"
  #check no of error found and  do task
 if(( $count >= 10))
    then
    echo "more oe equal to 10 finds"
   else
    echo  "less than 10 occurence"
   fi
整体流程如下:

  • 预处理输入以导出日期部分
  • 将日期转换为自纪元起的秒数
  • 根据给定的条件筛选自历元起的秒数
  • 从新纪元开始移除秒数
  • 输出
  • 总体来说,使用流在bash中工作。
    strtime
    来自
    dateutils
    包。像这样:

    # Extract the date+time part from within [..] and put it on the first column with tab
    sed 's/ \[\([^]]*\)\]/\1\t&/' "$input" |
    # For each line
    while IFS=$'\t' read -r date rest; do
        # Convert the date to seconds since epoch
        date=$(strptime -f "%s" -i "%a %b %d %H:%M:%S %Y" "$date")
        # Output the updated line
        printf "%s\t%s\n" "$date" "$rest"
    done |
    # Read it all in awk and compare second since epoch in the first field to given value
    awk -v "since=$(date -d'now -2 hours' +%s)" '$1 > since' |
    # Remove first field - ie. second since epoch
    cut -f2-
    

    不要使用反勾号“`”。改用
    $(…)
    。记住引用所有变量展开式是一条经验法则。检查脚本中最常见的错误。我认为在
    date
    strtime
    之间的某个地方,您可能会遇到时区问题(即小时数的差异)。

    我在这里作一般性评论。虽然你的时间格式很容易阅读,但正如你现在注意到的,它是非常不切实际的。所有的方法都试图使用可排序的时间格式,比如unix时间,或者如果你想阅读ISO8601,它会读“2020-08-20T09:28:51”哦,我明白了,你至少能告诉我如何使用上面的日期[Thu Aug 20 09:23:51 2020]这样的句子吗。当我grep时,这个grep并不把它作为单个参数,而是不同的字符串
    tail$input | grep$输入
    tail
    被忽略,你可以删除它。@KamilCuk哦,我明白了,谢谢你编辑了。你能告诉我为什么尽管如此作为参考,你的答案是将每个字符串用whitesape分开,并给我带来许多应该过滤的行。。我希望他们把整个日期作为一个字符串。
    把每个字符串用whitesape分开。
    我不知道这是什么意思。我发布的代码只是这个流程的一个例子——您可以只在
    awk
    中编写,也可以在任何其他工具中编写。我会补充一些意见。
    # Extract the date+time part from within [..] and put it on the first column with tab
    sed 's/ \[\([^]]*\)\]/\1\t&/' "$input" |
    # For each line
    while IFS=$'\t' read -r date rest; do
        # Convert the date to seconds since epoch
        date=$(strptime -f "%s" -i "%a %b %d %H:%M:%S %Y" "$date")
        # Output the updated line
        printf "%s\t%s\n" "$date" "$rest"
    done |
    # Read it all in awk and compare second since epoch in the first field to given value
    awk -v "since=$(date -d'now -2 hours' +%s)" '$1 > since' |
    # Remove first field - ie. second since epoch
    cut -f2-