मैं लेख मैं मिल सकता है के सभी पढ़ा है, यहां तक कि उनमें से कुछ समझा लेकिन एक अजगर newb के रूप में मैं अभी भी एक छोटे से खो और मदद :)मल्टी लाइन मिलान
मैं के लिए उम्मीद कर रहा हूँ मैं एक अनुप्रयोग विशिष्ट लॉग फ़ाइल से ब्याज की वस्तुओं को पार्स करने के लिए एक स्क्रिप्ट पर काम कर रहा हूं, प्रत्येक पंक्ति एक टाइम स्टैम्प से शुरू होती है जिसे मैं मिलान कर सकता हूं और मैं दो चीजों को परिभाषित कर सकता हूं कि मैं क्या हासिल करना चाहता हूं, कुछ आंशिक सामग्री और एक स्ट्रिंग जो मैं निकालना चाहता हूं उसे समाप्त कर दिया जाएगा।
मेरा मुद्दा बहु-रेखा है, ज्यादातर मामलों में प्रत्येक लॉग लाइन को एक नई लाइन के साथ समाप्त कर दिया जाता है लेकिन कुछ प्रविष्टियों में एसक्यूएल होता है जिसमें इसके भीतर नई लाइनें हो सकती हैं और इसलिए लॉग में नई लाइनें बनती हैं।
तो, एक सरल मामले में मैं इस हो सकता है:
re.compile('\[(0?[1-9]|[12][0-9]|3[01])(\/)(0?[1-9]|[12][0-9]|3[01])(\/)([0-9]{2}).*(milliseconds)')
हालांकि कुछ मामलों में लाइन हो सकता है:
[8/21/13 11:30:33:557 PDT] 00000488 SystemOut O 21 Aug 2013 11:30:33:557 [WARN] [MXServerUI01] [CID-UIASYNC-17464] BMXAA6720W - USER = (ABCDEF) SPID = (2526) app (ITEM) object (ITEM) : select * from item where ((status != 'OBSOLETE' and itemsetid = 'ITEMSET1') and (exists (select 1 from maximo.invvendor where (exists (select 1 from maximo.companies where ((contains(name,' $AAAA ') > 0)) and (company=invvendor.manufacturer and orgid=invvendor.orgid))) and (itemnum = item.itemnum and itemsetid = item.itemsetid)))) and (itemtype in (select value from synonymdomain where domainid='ITEMTYPE' and maxvalue = 'ITEM')) order by itemnum asc (execution took 2083 milliseconds)
यह सब एक लाइन जो मुझे इस के साथ मिलान कर सकते हैं के रूप में प्रकट होता है एसक्यूएल में तोड़ता है, जैसे कि मैं इसे अभी भी कैप्चर करना चाहता हूं (और संभावित रूप से रिक्त स्थान के साथ लाइन ब्रेक को प्रतिस्थापित करता हूं)। मैं वर्तमान में फाइल को एक समय में पढ़ रहा हूं जो स्पष्ट रूप से काम नहीं करेगा ...
- क्या मुझे पूरी फाइल को एक बार में संसाधित करने की आवश्यकता है? वे आमतौर पर आकार में 20 एमबी हैं। मैं पूरी फ़ाइल को कैसे पढ़ूं और इसके माध्यम से सिंगल या मल्टी-लाइन ब्लॉक की तलाश करूँ?
- मैं एक बहु-लाइन RegEx कैसे लिखूं जो पूरी चीज को एक पंक्ति पर मेल करेगा या इससे कई लाइनों में फैल जाएगा?
मेरा समग्र लक्ष्य इसे पैरामीटर करना है ताकि मैं लॉग प्रविष्टियों को निकालने के लिए इसका उपयोग कर सकूं जो प्रारंभिक स्ट्रिंग के विभिन्न पैटर्न (हमेशा एक पंक्ति की शुरुआत) से मेल खाते हैं, अंत स्ट्रिंग (जहां मैं कैप्चर करना चाहता हूं) और एक मूल्य जो उनके बीच एक पहचानकर्ता के रूप में है।
किसी भी मदद के लिए अग्रिम धन्यवाद!
क्रिस।
import sys, getopt, os, re
sourceFolder = 'C:/MaxLogs'
logFileName = sourceFolder + "/Test.log"
lines = []
print "--- START ----"
lineStartsWith = re.compile('\[(0?[1-9]|[12][0-9]|3[01])(\/)(0?[1-9]|[12][0-9]|3[01])(\/)([0-9]{2})(\)')
lineContains = re.compile('.*BMXAA6720W.*')
lineEndsWith = re.compile('(?:.*milliseconds.*)')
lines = []
with open(logFileName, 'r') as f:
for line in f:
if lineStartsWith.match(line) and lineContains.match(line):
if lineEndsWith.match(line) :
print 'Full Line Found'
print line
print "- Record Separator -"
else:
print 'Partial Line Found'
print line
print "- Record Separator -"
print "--- DONE ----"
अगला कदम, मेरे आंशिक लाइन के लिए मैं पढ़ना जारी रखने के जब तक मैं lineEndsWith खोजने के लिए और एक ब्लॉक करने के लिए लाइनों को इकट्ठा करेंगे।
मैं कोई विशेषज्ञ नहीं हूं इसलिए सुझाव हमेशा स्वागत है!
अद्यतन - तो मैं यह काम कर रहा हूं, उन सभी प्रतिक्रियाओं के लिए धन्यवाद जो चीजों को निर्देशित करने में मदद करते हैं, मुझे एहसास है कि यह सुंदर नहीं है और मुझे अपने अगर/elif गड़बड़ को साफ करने और इसे अधिक कुशल बनाने की आवश्यकता है लेकिन यह काम कर रहा है! पूरी सहायताके लिए शुक्रिया।
import sys, getopt, os, re
sourceFolder = 'C:/MaxLogs'
logFileName = sourceFolder + "/Test.log"
print "--- START ----"
lineStartsWith = re.compile('\[(0?[1-9]|[12][0-9]|3[01])(\/)(0?[1-9]|[12][0-9]|3[01])(\/)([0-9]{2})(\)')
lineContains = re.compile('.*BMXAA6720W.*')
lineEndsWith = re.compile('(?:.*milliseconds.*)')
lines = []
multiLine = False
with open(logFileName, 'r') as f:
for line in f:
if lineStartsWith.match(line) and lineContains.match(line) and lineEndsWith.match(line):
lines.append(line.replace("\n", " "))
elif lineStartsWith.match(line) and lineContains.match(line) and not multiLine:
#Found the start of a multi-line entry
multiLineString = line
multiLine = True
elif multiLine and not lineEndsWith.match(line):
multiLineString = multiLineString + line
elif multiLine and lineEndsWith.match(line):
multiLineString = multiLineString + line
multiLineString = multiLineString.replace("\n", " ")
lines.append(multiLineString)
multiLine = False
for line in lines:
print line
क्या आपने 're.DOTALL' ध्वज का उपयोग करने का प्रयास किया है? यद्यपि आपको इसके परिणामस्वरूप '। *' भाग आलसी ('। *?') बनाना होगा, क्योंकि जब आप लाइन से लाइन पढ़ रहे हैं, तो यह काम करेगा यदि आप पूरी फाइल को एक ही बार पढ़ते हैं। हालांकि मुझे स्मृति/प्रदर्शन प्रभाव के बारे में निश्चित नहीं है। – Jerry
आप पूरी फ़ाइल को पढ़ने का प्रयास कर सकते हैं और फिर टेक्स्ट को रेगेक्स के साथ विभाजित कर सकते हैं जो न्यूलाइन के बाद सीधे टाइमस्टैम्प से मेल खाता है। इससे आपको एकजुट एकल लॉग संदेशों की एक सूची मिलनी चाहिए, जब तक कि आपके उपयोगकर्ता अपने एसक्यूएल में '" \ n [8/21/13 11: 30: 33: 557 पीडीटी] "जैसी चीजें एम्बेड नहीं कर रहे हैं ... इस मामले में आप शायद कुछ अन्य समस्याएं हैं। –
अब मुझे आश्चर्य हो रहा है कि क्या मैं लाइन से लाइन पर वापस जाने से बेहतर होगा जैसे कि मैंने एक समय में एक पंक्ति पढ़ी, अगर लाइन मेरे "स्टार्ट" और "इसमें" मानों से मेल खाती है तो मेरे पास एक मैच है I फिर "एंड" मार्कर की जांच करने की आवश्यकता है या, अगर यह वहां नहीं है तब तक मुझे पढ़ने और जोड़ने की लाइनें नहीं रहती हैं। मुझे लगता है कि मैं भाग्यशाली हूं कि मुझे पता है कि शुरुआत और अंत हमेशा वहां रहेगा, मुझे बस उनकी तलाश करनी है। – Chris