【问题标题】:Python - Search for a specific time range in text file (sed -n equivalent)Python - 在文本文件中搜索特定时间范围(sed -n 等效)
【发布时间】:2017-06-12 10:18:50
【问题描述】:

我正在尝试制作一个从日志文件输出特定时间范围的 python 脚本(类似于下面列出的 sed 命令):

sed -n '/2017-01-26 18:00/ , /2017-01-26 18:02/p' /logfile.log
2017-01-26 18:00:00 2017-01-26 18:01:01 2017-01-26 18:01:02 2017-01-26 18:01:09 2017-01-26 18:01:09 2017-01-26 18:01:11 2017-01-26 18:02:01

我的 python 脚本正在搜索一个固定的字符串,而不像上面的 sed 命令(我怀疑我做错了什么,但我找不到错误 - 请检查下面的代码):

请指出应该更改代码的位置,并建议代码增强。谢谢!

#!/usr/bin/python
import datetime, time, os, sys, re
from datetime import timedelta
counter = 0
avgtime = 0

now = datetime.datetime.utcnow()
pasttime = now - datetime.timedelta(minutes=5)

timestamp = now.strftime("%y%m%d")
fiveago   = now - timedelta(minutes=5,seconds=now.second)
current   = now.strftime("%Y-%m-%d %H:%M")
pasttime  = fiveago.strftime("%Y-%m-%d %H:%M")
pattern   = str(current + "|" + pasttime)

f = open('/logs/' + sys.argv[1] + '/' + 'u_ex' + timestamp + '.log', 'r')
for line in f:
        if "POST" in line:
                if re.search(pattern, line, re.IGNORECASE):
                        date = line.split(' ')[1]
                        time = line.split(' ')[14]
                        avgtime += int(time)
                        counter += 1
                        print(date,time)
f.close()

print(pattern)
print("Total amount of time: ",counter)
print("Total scan time: ",avgtime)
print("Average scan time: ",avgtime / counter)

【问题讨论】:

  • sed命令其实是这样的:sed -n '/2017-01-26 18:00/ , /2017-01-26 18:02/p' /logfile.log
  • 代码应该做什么?您的 sed 命令似乎只显示时间范围内的行,但您的 python 代码确实计算了一些平均值?
  • 是的,它得到了 SQL 事务中所用时间的算术平均值......但我现在遇到的问题是让正则表达式以与 sed 命令相同的方式工作
  • 您的问题到底是什么?您似乎对这里编写的代码不满意,但您还没有解释您需要帮助的地方。 How to Ask
  • @HåkenLid 他在 cmets 中解释过,我现在得到了问题并正在研究解决方案

标签: python sed


【解决方案1】:

您的解决方案的问题在于您只寻找两个“边缘时间”。在您的 3 分钟时间范围示例中,这是 18:0018:02

sed 命令的作用是:

sed -n '/2017-01-26 18:00/ , /2017-01-26 18:02/p' /logfile.log
  1. 遍历行而不打印 (-n)
  2. 只要 sed 找到 2017-01-26 18:00,它就会开始打印所有行
  3. 只要 sed 找到 2017-01-26 18:02,它就会停止打印

在您的示例中,您的正则表达式模式是:

2017-01-26 18:00|2017-01-26 18:02

并且只会找到任一 18:00 18:02。因此,您可以执行以下操作之一:

  1. 解析行外日期并与时间范围进行比较,如Shijos answer
  2. 模拟 sed,如 theamks answer,但请注意:这仅在文件中同时存在两个“边缘时间戳”时才有效
  3. pimp 你的正则表达式,所以它也会搜索两者之间的时间:

    pattern = "|".join([(now-timedelta(minutes=i)).strftime("%Y-%m-%d %H:%M") for i in range(6)])
    

    这将产生例如:

    '2016-01-26 18:00|2016-01-26 17:59|2016-01-26 17:58|2016-01-26 17:57|2016-01-26 17:56|2016-01-26 17:55'
    

【讨论】:

    【解决方案2】:

    IIUC,你需要你通过的时间戳之间的日志中的输入。

    import datetime, time, os, sys, re
    from datetime import timedelta
    counter = 0
    avgtime = 0
    
    now = datetime.datetime.utcnow()
    pasttime = now - datetime.timedelta(minutes=100000)
    
    timestamp = now.strftime("%y%m%d")
    fiveago   = now - timedelta(minutes=5,seconds=now.second)
    current   = now.strftime("%Y-%m-%d %H:%M")
    pasttime  = fiveago.strftime("%Y-%m-%d %H:%M")
    pattern   = str(current + "|" + pasttime)
    
    print "Start time: ", pasttime ,"End time: ",current ,"\n\n"
    
    filename ='/logs/' + sys.argv[1] + '/' + 'u_ex' + timestamp + '.log'
    with open(filename, 'r') as f:
        contents = f.readlines()
    for line in contents:
        if "POST" in line:
            date = line.split(' ')[1]
            time = line.split(' ')[14]
            logdatetime=date+" "+time
    
            if logdatetime <= current and logdatetime >= pasttime:
                print "yes, within the interval : " ,logdatetime
    

    输出

    Start time:  2017-01-26 20:23 End time:  2017-01-26 20:28 
    
    
    yes, within the interval :  2017-01-26 20:23:20
    yes, within the interval :  2017-01-26 20:23:01
    yes, within the interval :  2017-01-26 20:23:02
    

    用于此的输入

    POST 2017-01-26 20:23:20 XX
    POST 2017-01-26 20:23:01 XC
    POST 2017-01-26 20:23:02 CV
    POST 2017-01-26 20:20:09 DAF
    POST 2017-01-26 20:20:09 fASF
    POST 2017-01-26 20:20:11 Sfas
    POST 2017-01-26 20:20:01 fsAf
    POST 2017-01-26 20:20:02 asf
    POST 2017-01-26 20:20:03 asf
    

    【讨论】:

      【解决方案3】:

      我不明白问题出在哪里,但您要求 sed 等效于您的命令,所以这里是 python 的精确翻译:

      import sys, re
      use = False
      for line in open('/logfile.log'):
         if re.search('2017-01-26 18:00', line): use = True
         if use: sys.stdout.write(line)
         if re.search('2017-01-26 18:02', line): use = False
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多