【问题标题】:How to print 3rd from bottom line in file?如何从文件的最后一行打印第三个?
【发布时间】:2018-07-03 15:03:12
【问题描述】:

我想读取并打印 date.log 中倒数第三行。这在 line_from_bottom_line 变量中指定。 日志在任何时候都可以有任意数量的行。

以下是日志的示例:

192.168.80.231 May 8 2018 18:45:00
192.168.80.231 July 30 2018 09:46:48
192.168.80.231 July 2 2018 14:37:14

如果日志只有3行,则打印else行:

 line_number[x1] = [(index,log_time)]

输出将是:

(1, '18:45:00')

这不是我想要的。

如果有 4 行或更多行,则打印的行格式为:

2018:8:18:45:00

这就是我想要的。

我认为我下面的代码正在移动到底线并减去 3。所以如果 4 行不存在,它不知道 打印什么。即使没有 4 个或更多,如何更改它以便打印底线的第 3 个 日志中的行?

old_time = (line_number[x1][-(line_from_bottom_line)].__str__())

from datetime import datetime, date, time

# this would be the third from last line
line_from_bottom_line = 3

date_order  = 2
time_order  = 4
year_order  = 3

present = datetime.now()

def main():
    logfile = open('krinkov.log', 'r+')
    line_number = dict()
    for index,line in enumerate(logfile,1):  # scan lines
        if line in ['\n', '\r\n']:  # Error Checking: if not enough lines in var .log
            print("Not enough lines.")
            return
        if line:
            x1 = line.split()[0]  # if line, get IP address
            log_day   = line.split()[date_order]
            log_time  = line.split()[time_order]  # This will already be in the format of hh:mm:ss
            log_year  = line.split()[year_order]
        if x1 in line_number :  # if ip address on line
            line_number[x1].append((log_year + ":" + log_day + ":" + log_time))

        else:
            line_number[x1] = [(index,log_time)]

    if x1 in line_number and len(line_number.get(x1,None)) > 1:

        # Below is where I am having issues.
        # If there are not 4 or more lines in the log, an error occurs.
        old_time = (line_number[x1][-line_from_bottom_line])
        print(old_time)

        # ** get last line number.  Print that line number.  then subtract 2 from it
        # old_time = that new number


    else:
        print('Nothing')
main()

【问题讨论】:

  • 为什么要使用python?在控制台中一个简单的tail -n3 your_file.txt | head -n1 就可以做到这一点
  • 不要打电话给obj.__str__()__ 通常表明您不应该从外部调用此方法。相反,请使用str(obj)。但是您的打印语句已经这样做了,因此您可以完全放弃它。
  • 2 也不需要括号,line_number[x1][-2] 就足够了。
  • 对不起,我的意思是使用 old_time = (line_number[x1][-line_from_bottom_line])

标签: python python-2.7


【解决方案1】:

问题:查看您在line_number 字典中添加新元素的位置:

if x1 in line_number :  # if ip address on line
    line_number[x1].append((log_year + ":" + log_day + ":" + log_time))

else:
    line_number[x1] = [(index,log_time)]

如果字典包含 IP 地址(即else 部分被执行),则使用包含元素(index,log_time) 的列表的字典创建 IP 字段,其中是一个有两个元素的元组。

之后,如果 IP 地址已经包含(if 部分被执行),您只需添加 (log_year + ":" + log_day + ":" + log_time),即 字符串 log_year + ":" + log_day + ":" + log_time。这是因为 Python 中的 (elem) 被解压为 elem。如果你想创建一个包含单个元素的元组,你必须写(elem,)

考虑到这一点,您的line_number 字典中的每个值似乎都类似于这样(检查一下!):

[(1, '18:45:00'), "2018:8:18:45:00", "2018:8:18:45:00", "2018:8:18:45:00" ... ]

修复:将上述摘录中的[(index,log_time)] 更改为[(log_year + ":" + log_day + ":" + log_time)] 应该可以解决您的问题。这是不好的编码风格,因为你要写两次相同的东西。更好的解决方案是将上面的代码替换为以下行:

line_number[x1] = line_number.get(x1, []) + [f"{log_year}:{log_day}:{log_time}"]

【讨论】:

  • 谢谢!我应该抓住它。哈哈
  • 欢迎您。作为提示,在这里和那里插入一些print() 语句可以澄清发生了什么。调试器在这方面做得更好;)
猜你喜欢
  • 1970-01-01
  • 2022-06-15
  • 1970-01-01
  • 2010-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多