2012-10-24 16 views
6

के लिए पायथन पार्सिंग लॉग फ़ाइल यह मेरा पहला सवाल है जो यहां स्टैक ओवरफ्लो पर पूछा गया है और वास्तव में इस समुदाय का हिस्सा बनने की उम्मीद कर रहा हूं। मैं कार्यक्रम के लिए नया हूं और पाइथन कई लोगों द्वारा सबसे अधिक अनुशंसित पहला कार्यक्रम था।आईपी पते और प्रोटोकॉल

वैसे भी। मैं जो इस तरह दिखता है एक लॉग फ़ाइल है:

"No.","Time","Source","Destination","Protocol","Info" 
"1","0.000000","120.107.103.180","172.16.112.50","TELNET","Telnet Data ..." 
"2","0.000426","172.16.112.50","172.16.113.168","TELNET","Telnet Data ..." 
"3","0.019849","172.16.113.168","172.16.112.50","TCP","21582 > telnet [ACK]" 
"4","0.530125","172.16.113.168","172.16.112.50","TELNET","Telnet Data ..." 
"5","0.530634","172.16.112.50","172.16.113.168","TELNET","Telnet Data ..." 

और मैं यह परिणाम के रूप में इस तरह दिखेगा बनाने के लिए अजगर का उपयोग कर लॉग फ़ाइल पार्स करने के लिए चाहता था:

आईपी 135.13.216.191 प्रोटोकॉल से गणना: (आईएमएफ 1) (एसएमटीपी 38) (टीसीपी 24) (कुल: 63)

मैं करूंगा वास्तव में कुछ की तरह HEL इस समस्या से निपटने के लिए किस मार्ग पर लेना चाहिए, क्या मुझे इसके माध्यम से सूचियों और लूप का उपयोग करना चाहिए या शब्दकोश/टुपल्स?

आपकी मदद के लिए अग्रिम धन्यवाद!

+1

'135.13.216.191' कहां से आया? – Eric

+0

यह सिर्फ एक उदाहरण था, लेकिन यह गंतव्य क्षेत्र से एक पंक्ति से था। –

उत्तर

0

सबसे पहले आप पाठ फ़ाइल में पढ़ने के लिए चाहता हूँ

# Open the file 
file = open('log_file.csv') 
# readlines() will return the data as a list of strings, one for each line 
log_data = file.readlines() 
# close the log file 
file.close() 

एच के लिए एक शब्दकोश सेट अप करें वर्ष अपने परिणामों

results = {} 

अब अपने डेटा, एक समय में एक लाइन पर पुनरावृति, और शब्दकोश

for entry in log_data: 
    entry_data = entry.split(',') 
    # We are going to have a separate entry for each source ip 
    # If we haven't already seen this ip, we need to make an entry for it 
    if entry_data[2] not in results: 
     results[entry_data[2]] = {'total':0} 
    # Now check to see if we've seen the protocol for this ip before 
    # If we haven't, add a new entry set to 0 
    if entry_data[4] not in results[entry_data[2]]: 
     results[entry_data[2]][entry_data[4]] = 0 
    # Now we increment the count for this protocol 
    results[entry_data[2]][entry_data[4]] += 1 
    # And we increment the total count 
    results[entry_data[2]]['total'] += 1 

में प्रोटोकॉल रिकॉर्ड एक बार जब आप सब कुछ गिना बाद, बस अपने मायने रखता है और प्रिंट से अधिक पुनरावृति परिणाम

for ip in results: 
    # Here we're printing a string with placeholders. the {0}, {1} and {2} will be filled 
    # in by the call to format 
    print "from: IP {0} Protocol Count: {1})".format(
     ip, 
     # And finally create the value for the protocol counts with another format call 
     # The square braces with the for statement inside create a list with one entry 
     # for each entry, in this case, one entry for each protocol 
     # We use ' '.join to join each of the counts with a string 
     ' '.join(["({0}: {1})".format(protocol, results[ip][protocol] for protocol in results[ip])])) 
+0

धन्यवाद स्कंकवाफ्ले वास्तव में कोड की सादगी पसंद कर रहा हूं। –

+1

@ जॉनस्मिथ: आप पागल हो जाएंगे कि अंतर्निहित ['csv' मॉड्यूल] (http://docs.python.org/library/csv.html) का उपयोग न करें, अपनी सीएसवी फ़ाइल को पार्स करने के लिए – Eric

+0

@DSM मुझे लगता है कि आप ठीक है, और मेरे जवाब पर विचार करने के लिए कोई वोट नहीं है, और एरिक के पास 7 है, शायद उसका जवाब होना चाहिए। यदि ओपी एरिक के स्वीकृत उत्तर को स्विच करेगा, तो मैं मेरा हटाना ठीक कर दूंगा। – Skunkwaffle

9

आप का उपयोग कर फ़ाइल को पार्स कर सकते हैं csv module:

import csv 

with open('logfile.txt') as logfile: 
    for row in csv.reader(logfile): 
     no, time, source, dest, protocol, info = row 
     # do stuff with these 

मैं काफी नहीं बता सकता कि तुम क्या कह रहे हैं, लेकिन मुझे लगता है कि आप चाहते हैं:

import csv 
from collections import defaultdict 

# A dictionary whose values are by default (a 
# dictionary whose values are by default 0) 
bySource = defaultdict(lambda: defaultdict(lambda: 0)) 

with open('logfile.txt') as logfile: 
    for row in csv.DictReader(logfile): 
     bySource[row["Source"]][row["Protocol"]] += 1 

for source, protocols in bySource.iteritems(): 
    protocols['Total'] = sum(protocols.values()) 

    print "From IP %s Protocol Count: %s" % (
     source, 
     ' '.join("(%s: %d)" % item for item in protocols.iteritems()) 
    ) 
+0

आपके उत्तर के लिए धन्यवाद। तो क्या मैं बस इसके परिणामों के माध्यम से लूप करता हूं और प्रत्येक आईपी पते के लिए प्रत्येक प्रोटोकॉल की संख्या की गणना करता हूं?धन्यवाद –

+0

@ जॉनस्मिथ: मेरा कोड पहले से ही यह करता है - क्या आपने मेरा अपडेट याद किया? – Eric

+0

धन्यवाद, बस अपडेट देखा। बहुत बहुत धन्यवाद एरिक मैं वास्तव में मदद की सराहना करता हूं। यह भी ठीक होगा अगर फ़ाइल का उपयोग कर रहे हैं तो 1-2 जीबी आकार की तरह है? –

1

मैं पहली से शुरू होगा फ़ाइल को एक सूची में पढ़ना:

contents = [] 
with open("file_path") as f: 
    contents = f.readlines() 

फिर आप प्रत्येक पंक्ति को अपनी सूची में विभाजित कर सकते हैं:

ips = [l[1:-1].split('","') for l in contents] 

हम तो एक dict में इन मैप कर सकते हैं:

sourceIps = {} 
for ip in ips: 
    try: 
     sourceIps[ip[2]].append(ip) 
    except: 
     sourceIps[ip[2]] = [ip] 

और अंत में परिणाम प्रिंट आउट:

for ip, stuff in sourceIps.iteritems(): 
    print "From {0} ... ".format(ip, ...) 
+0

पीएस में लोड नहीं करता है: यह मुख्य रूप से कुछ प्रोग्रामिंग संरचनाओं का एक उदाहरण है जिसका उपयोग पायथन में किया जा सकता है, पाइथन का उपयोग करके इस समस्या के 'इष्टतम' समाधान की तुलना में रैथर, चूंकि ओपी प्रारंभिक प्रोग्रामिंग जानकारी की तलाश में लग रहा था। – Will

+0

बहुत बहुत धन्यवाद। इससे सूची स्थापित करने में मदद मिली लेकिन मैं प्रत्येक आईपी पते पर अद्वितीय प्रोटोकॉल की संख्या कैसे गिनता? इसके अलावा प्रत्येक आईपी पते को विभिन्न प्रोटोकॉल के साथ कई बार दोहराया जाता है। –

+0

मानचित्र में अनुवाद जोड़ने के लिए अपडेट किया गया – Will

संबंधित मुद्दे