3

複数の IP アドレスを含むファイルがあります。txt の 4 行に約 900 個の IP があります。出力を 1 行あたり 1 IP にしたいと考えています。どうすればこれを達成できますか? 他のコードに基づいて、これを思いつきましたが、複数の IP が 1 行にあるため失敗します。

import sys
import re

try:
    if sys.argv[1:]:
        print "File: %s" % (sys.argv[1])
        logfile = sys.argv[1]
    else:
        logfile = raw_input("Please enter a log file to parse, e.g /var/log/secure: ")
    try:
        file = open(logfile, "r")
        ips = []
        for text in file.readlines():
           text = text.rstrip()
           regex = re.findall(r'(?:[\d]{1,3})\.(?:[\d]{1,3})\.(?:[\d]{1,3})\.(?:[\d]{1,3})$',text)
           if regex is not None and regex not in ips:
               ips.append(regex)

        for ip in ips:
           outfile = open("/tmp/list.txt", "a")
           addy = "".join(ip)
           if addy is not '':
              print "IP: %s" % (addy)
              outfile.write(addy)
              outfile.write("\n")
    finally:
        file.close()
        outfile.close()
except IOError, (errno, strerror):
        print "I/O Error(%s) : %s" % (errno, strerror)
4

4 に答える 4

3

式の$アンカーにより、最後のエントリ以外を見つけることができません。それを削除してから、によって返されるリストを使用します.findall()

found = re.findall(r'(?:[\d]{1,3})\.(?:[\d]{1,3})\.(?:[\d]{1,3})\.(?:[\d]{1,3})',text)
ips.extend(found)

re.findall()は常にリストを返しますが、これは空である可能性があります。

  • 一意のアドレスのみが必要な場合は、リストの代わりにセットを使用してください。
  • IP アドレスを検証する必要がある場合 (私用ネットワークとローカル アドレスを無視することを含む)、ipaddress.IPV4Address()クラスの使用を検討してください。
于 2012-12-24T23:52:36.757 に答える
1

findall 関数は一致の配列を返します。各一致を反復処理するわけではありません。

regex = re.findall(r'(?:[\d]{1,3})\.(?:[\d]{1,3})\.(?:[\d]{1,3})\.(?:[\d]{1,3})$',text)
if regex is not None:
    for match in regex:
        if match not in ips:
            ips.append(match)
于 2012-12-24T23:44:23.140 に答える
0

re.MULTILINEフラグなし$では、文字列の末尾のみに一致します。

デバッグを容易にするために、コードをいくつかの部分に分割して、個別にテストできるようにします。

def extract_ips(data):
    return re.findall(r"\d{1,3}(?:\.\d{1,3}){3}", data)

入力ファイルが小さく、ips の元の順序を保持する必要がない場合:

with open(filename) as infile, open(outfilename, "w") as outfile:
    outfile.write("\n".join(set(extract_ips(infile.read()))))

さもないと:

with open(filename) as infile, open(outfilename, "w") as outfile:
    seen = set()
    for line in infile:
        for ip in extract_ips(line):
            if ip not in seen:
               seen.add(ip)
               print >>outfile, ip
于 2012-12-25T01:08:47.650 に答える