Tôi đã đọc tất cả các bài viết tôi có thể tìm, thậm chí hiểu một vài trong số họ nhưng như một newb Python tôi vẫn còn một chút mất và hy vọng để được giúp đỡ :)nhiều đường Matching bằng Python
tôi đang làm việc trên một kịch bản để phân tích các mục quan tâm ra khỏi tệp nhật ký cụ thể của ứng dụng, mỗi dòng bắt đầu bằng dấu thời gian mà tôi có thể khớp và tôi có thể xác định hai thứ để xác định thứ tôi muốn chụp, một số nội dung một phần và chuỗi đó sẽ là chấm dứt những gì tôi muốn trích xuất.
Vấn đề của tôi là đa dòng, trong hầu hết các trường hợp mỗi dòng đăng nhập được kết thúc bằng một dòng mới nhưng một số mục chứa SQL có thể có dòng mới bên trong và do đó tạo ra các dòng mới trong nhật ký.
Vì vậy, trong một trường hợp đơn giản, tôi có thể có điều này:
[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)
này tất cả dường như một dòng mà tôi có thể phù hợp với điều này:
re.compile('\[(0?[1-9]|[12][0-9]|3[01])(\/)(0?[1-9]|[12][0-9]|3[01])(\/)([0-9]{2}).*(milliseconds)')
Tuy nhiên, trong một số trường hợp có thể có dòng phá vỡ trong SQL, như vậy tôi muốn vẫn nắm bắt nó (và có khả năng thay thế các ngắt dòng với không gian). Hiện tại, tôi đang đọc tập tin tại một thời điểm rõ ràng là không hoạt động ...
- Tôi có cần xử lý toàn bộ tệp trong một lần không? Chúng thường có kích thước 20mb. Làm cách nào để đọc toàn bộ tệp và lặp lại thông qua tìm kiếm các khối đơn hoặc nhiều dòng?
- Làm cách nào để viết RegEx nhiều dòng khớp với toàn bộ nội dung trên một dòng hoặc trên toàn bộ dòng được trải rộng trên nhiều dòng?
Mục tiêu tổng thể của tôi là tham số hóa để tôi có thể sử dụng nó để trích xuất mục nhập nhật ký khớp với các mẫu khác nhau của chuỗi bắt đầu (luôn bắt đầu một dòng), chuỗi kết thúc (nơi tôi muốn chụp) và một giá trị nằm giữa chúng như một định danh.
Cảm ơn bạn đã giúp đỡ!
Chris.
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 ----"
Bước tiếp theo, cho dòng một phần của tôi, tôi sẽ tiếp tục đọc cho đến khi tôi tìm thấy dòngEndsWith và lắp ráp các dòng vào một khối.
Tôi không có chuyên gia để đề xuất luôn được chào đón!
CẬP NHẬT - Vì vậy, tôi có nó hoạt động, nhờ vào tất cả các câu trả lời đã giúp trực tiếp mọi thứ, tôi nhận ra nó không đẹp và tôi cần dọn dẹp nếu/elif mess và làm cho nó hiệu quả hơn nhưng CNTT LÀM VIỆC! Cảm ơn vì sự giúp đỡ.
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
Bạn đã thử sử dụng cờ 're.DOTALL' chưa? Bạn sẽ phải làm cho phần '. *' Lười biếng ('. *?') Như một hệ quả của điều này mặc dù và vì bạn đang đọc từng dòng, nó sẽ hoạt động nếu bạn đọc toàn bộ tập tin cùng một lúc. Tôi không chắc chắn về ý nghĩa bộ nhớ/hiệu suất tuy nhiên. – Jerry
Bạn có thể thử đọc toàn bộ tệp và sau đó tách văn bản bằng một regex phù hợp với dấu thời gian ngay sau dòng mới. Điều đó sẽ giúp bạn có được danh sách các thông điệp nhật ký đơn kề nhau, trừ khi người dùng của bạn đang nhúng những thứ như '" \ n [8/21/13 11: 30: 33: 557 PDT] "' vào SQL của họ ... trong trường hợp đó bạn có lẽ đã có một số vấn đề khác. –
Tôi bắt đầu băn khoăn không biết liệu tôi có nên quay trở lại từng dòng một hay không, nếu tôi đọc một dòng tại một thời điểm, nếu dòng khớp với giá trị "bắt đầu" và "chứa" của tôi, tôi có một kết quả phù hợp sau đó cần kiểm tra điểm đánh dấu "kết thúc" hoặc nếu không có thì hãy đọc và thêm các dòng cho đến khi tôi tìm thấy nó. Tôi nghĩ tôi may mắn vì tôi biết sự bắt đầu và kết thúc sẽ luôn ở đó, tôi chỉ cần tìm chúng. – Chris