[英]python parse file for ip addresses
我有一個包含多個 IP 地址的文件。 4行txt大約有900個IP。 我希望輸出為每行 1 個 IP。 我怎樣才能做到這一點? 基於其他代碼,我想出了這個,但它失敗了,因為多個 IP 位於單行上:
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)
表達式中的$
錨點阻止您找到除最后一個條目之外的任何內容。 刪除它,然后使用.findall()
返回的列表:
found = re.findall(r'(?:[\d]{1,3})\.(?:[\d]{1,3})\.(?:[\d]{1,3})\.(?:[\d]{1,3})',text)
ips.extend(found)
re.findall()
將始終返回一個列表,該列表可能為空。
ipaddress.IPV4Address()
類。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)
從文件中提取 IP 地址
我在這個討論中回答了一個類似的問題。 簡而言之,這是一個基於我正在進行的項目之一的解決方案,用於從不同類型的輸入數據(例如字符串、文件、博客帖子等)中提取基於網絡和主機的指標: https : //github.com/JohnnyWachter/intel
我將導入IPAddresses和Data類,然后使用它們以下列方式完成您的任務:
#!/usr/bin/env/python
"""Extract IPv4 Addresses From Input File."""
from Data import CleanData # Format and Clean the Input Data.
from IPAddresses import ExtractIPs # Extract IPs From Input Data.
def get_ip_addresses(input_file_path):
""""
Read contents of input file and extract IPv4 Addresses.
:param iput_file_path: fully qualified path to input file. Expecting str
:returns: dictionary of IPv4 and IPv4-like Address lists
:rtype: dict
"""
input_data = [] # Empty list to house formatted input data.
input_data.extend(CleanData(input_file_path).to_list())
results = ExtractIPs(input_data).get_ipv4_results()
return results
現在您有了一個列表字典,您可以輕松訪問您想要的數據並以您想要的任何方式輸出它。 下面的例子使用了上面的函數; 將結果打印到控制台,並將它們寫入指定的輸出文件:
# Extract the desired data using the aforementioned function. ipv4_list = get_ip_addresses('/path/to/input/file') # Open your output file in 'append' mode. with open('/path/to/output/file', 'a') as outfile: # Ensure that the list of valid IPv4 Addresses is not empty. if ipv4_list['valid_ips']: for ip_address in ipv4_list['valid_ips']: # Print to console print(ip_address) # Write to output file. outfile.write(ip_address)
沒有re.MULTILINE
標志$
僅在字符串的末尾匹配。
為了使調試更容易,將代碼分成幾個可以獨立測試的部分。
def extract_ips(data):
return re.findall(r"\d{1,3}(?:\.\d{1,3}){3}", data)
正則表達式會過濾掉一些有效的2130706433
,例如2130706433
、 "1::1" 。
相反,正則表達式匹配無效字符串,例如999.999.999.999
。 您可以使用socket.inet_aton()
或更通用的socket.inet_pton()
驗證 ip 字符串。 您甚至可以在不搜索 ip 的情況下將輸入分成幾部分,並使用這些函數來保持有效的 ip。
如果輸入文件很小並且您不需要保留 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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.