【问题标题】:Finding new IP in a file在文件中查找新 IP
【发布时间】:2010-06-10 18:10:57
【问题描述】:

我有一个名为“IP”的 IP 地址文件。当我从日志中解析新 IP 时,我想在添加之前查看新 IP 是否已经在文件 IP 中。我知道如何将新 IP 添加到文件中,但无法查看新 IP 是否已在文件中。

!/usr/bin/python
from IPy import IP
IP = IP('192.168.1.2')
#f=open(IP('IPs', 'r'))  #This line doesn't work
f=open('IPs', 'r')    # this one doesn't work 
for line in f:
    if IP == line:
       print "Found " +IP +" before"
f.close()

在“IPs”文件中,每个 IP 地址都在它自己的行上。因此:

222.111.222.111
222.111.222.112

还尝试将文件 IP 放入数组中,但也没有好运。 有什么想法吗?

谢谢,

加里

【问题讨论】:

  • 这应该有一个 Python 标签。
  • 嗯,这个问题的问题具有误导性,您似乎遇到了 Python 文件访问问题,而不是文件搜索
  • 听起来打开的文件没有找到名为 IPs 的文件 - 您确定不是 IPs.txt 或类似文件吗?你得到的确切错误是什么?
  • 你没有给出任何错误信息或告诉什么不能按预期工作,你能更准确吗?
  • 不太确定,但我认为我不需要文件扩展名。我想从我的日志文件中获取一个 IP 并将其添加到我已经拥有的 IP 列表中。但是如果它已经在列表中,我不想将它添加到列表中。所以我必须搜索列表以确保新 IP 尚未列出。

标签: python ironpython ip-address compare


【解决方案1】:
iplist = []

# With takes care of all the fun file handling stuff (closing, etc.)
with open('ips.txt', 'r') as f:
    for line in f:
        iplist.append(line.strip())   # Gets rid of the newlines at the end

# Change the above to this for Python versions < 2.6
f = open('ips.txt', 'r')
for line in f:
    iplist.append(line.strip())
f.close()

newip = '192.168.1.2'

if newip not in iplist:
    f = open('ips.txt', 'a') # append mode, please
    f.write(newip+'\n')

现在您的 IP 在列表 (iplist) 中,您可以轻松地将您的新 IP 添加到其中 iplist.append(newip) 或做任何您想做的事情。


编辑:

一些学习 Python 的优秀书籍: 如果您担心编程很困难,那么有一本面向儿童的书,但老实说,我发现它既易于理解又内容丰富。 Snake Wrangling for Kids

另一个学习 Python 的好资源是How to Think Like a Computer Scientist

Python 官方网站上还有tutorial。和之前的比起来有点干。

Tutor@python.org 邮件列表的主要贡献者之一 Alan Gauld 的 this tutorial 非常好,也适用于 Python 3。他还提供了一些其他语言进行比较。

如果你想要一本好的死树书,我听说 Wesley Chun 的 Core Python Programming 是一个非常好的资源。他还经常为 Python 导师列表做出贡献。

tutor list 是另一个了解 Python 的好地方 - 阅读、回复和提出您自己的问题。实际上,我通过尝试回答尽可能多的问题来学习我的大部分 Python。如果您想学习 Python,我强烈建议您订阅导师列表。

【讨论】:

  • 使用集合而不是列表可以加快查找速度。
  • Wayne,您的代码按我需要的方式运行,非常感谢!但我认为我正在放弃并继续使用 Bash/grep。这个 python 脚本正在运行的盒子正在运行 Python 2.4,它是一个生产盒子。我的机器正在运行 Python 2.6.5。管理员近期没有升级计划。很抱歉,我之前没有提到这一点,我认为这无关紧要,但确实如此。
  • 啊,是的。至少如果你使用with - 我会为 提供类似的代码
  • 感谢“# Gets rid of the newlines at the end”评论,因为我不确定 line.strip 的用途。
  • 考虑到您如何使用它,您为什么还要尝试将它们加载到列表、散列或集合中?如果您要读取整个文件,请在循环中进行检查!
【解决方案2】:

这是一个微不足道的代码,但我认为它在 Python 中又短又漂亮,所以我会这样写:

ip = '192.168.1.2'

lookFor = ip + '\n'
f = open('ips.txt', 'a+')
for line in f:
    if line == lookFor:
        print 'found', ip, 'before.'
        break
else:
    print ip, 'not found, adding to file.'
    print >>f, ip
f.close()

它以附加模式打开文件,读取,如果没有找到(这就是 elsefor 所做的 - 如果循环正常退出而不是通过中断执行) - 附加新 IP。哒哒!

当您拥有大量 IP 时,现在将无效。这是我想到的另一个 hack,它使用每 1 个 IP 1 个文件作为标志:

import os

ip = '192.168.1.2'

fname = ip + '.ip'
if os.access(fname, os.F_OK):
    print 'found', ip, 'before.'
else:
    print ip, 'not found, registering.'
    open(fname, 'w').close()

为什么这么快?因为现在大多数文件系统(除了 Windows 上的 FAT 但 NTFS 可以)将目录中的文件列表组织成 B 树结构,因此检查文件是否存在是一个快速操作 O(log N) 而不是枚举整个列表。

(我并不是说这是实用的 - 取决于您希望看到的 IP 数量和您的系统管理员的善意。)

【讨论】:

  • 分离文件的好主意!刚刚使用 65K IP (192.168.*.*) 进行了测试。日志解析需要 9414 us,而文件系统检查需要 50 us(3 次测试的平均值,EXT4)。快了近200倍!获得赞成票(:
【解决方案3】:

你为什么需要这个IP?使用简单的字符串。

!#/usr/bin/env python

ip = "192.168.1.2" + "\n" ### Fixed -- see comments
f = open('IPs', 'r')
for line in f:
    if line.count(ip):
       print "Found " + ip
f.close()

此外,这看起来更像是 grep 和朋友的任务。

【讨论】:

  • 我已经在 grep 中做了这个并且它有效。但是一位同事建议我学习 python,我喜欢 python。
    关于你的代码,如果你将 192.168.1.22 放在文件 IP 中,这段代码会显示“找到 192.168.1.2”,这就是为什么你需要“从 IPy 导入 IP”的东西。
  • 确实有一个错误,但很容易修复:将line.count(ip) 替换为line==ip 并将上面的定义更改为ip = "192.168.1.2" + "\n"(最好在循环之外执行此操作而不是使用 strip()或内部多次串联)
  • 是的,我的错,感谢修复。 count() 用于忽略前导空格(如果有)。如果您确定 IP 前没有前导空格,EnTerr 对+ "\n" 的建议是正确的选择。否则,请考虑使用正则表达式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-12
  • 1970-01-01
  • 2012-06-12
  • 1970-01-01
  • 1970-01-01
  • 2018-03-15
相关资源
最近更新 更多