解析.log文件然后在访问中排序

时间:2017-06-26 13:45:14

标签: python excel ms-access

我正在编写一个解析程序,在一些关键字后搜索100多个.log文件,然后将这些单词放在不同的数组中,并将单词分成excel中的列。现在我想自动在Access中对它们进行排序,以便我可以处理不同的.log文件组合。我可以从我的Excel文件“复制粘贴”到Access,但这样效率很低并且会出现一些错误...我希望它是“自动的”。我是Access的新手,不知道如何从python链接到Access,我已经尝试过这样做,就像我对Excel做的那样但是没有工作并开始寻找OBDC但是有一些问题......

import glob   # includes
import xlwt  # includes
from os import listdir  # includes
from os.path import isfile, join    # includes


def logfile(filename, tester, createdate,completeresponse):
    # Arrays for strings
    response = []
    message = []
    test = []
    date = []

    with open(filename) as filesearch:   # open search file
        filesearch = filesearch.readlines()   # read file

    for line in filesearch:
        file = filename[39:]    # extract filename [file]
        for lines in filesearch:
            if createdate in lines:   # extract "Create Time" {date}
                date.append(lines[15:34])
            if completeresponse in lines:
                response.append(lines[19:])

        print('pending...')

        i = 1   # set a number on log {i}
        d = {}
        for name in filename:
            if not d.get(name, False):
                d[name] = i
                i += 1

        if tester in line:
            start = '-> '
            end = ':\ '                                                     #  |<----------->|
            number = line[line.find(start)+3: line.find(end)]        #Tester -> 1631 22 F1 2E :\ BCM_APP_31381140 AJ \ Read Data By Identifier \
            test.append(number)   # extract tester {test}
                                                                    #              |<--------------------------------------------
            text = line[line.find(end)+3:]             # Tester -> 1631 22 F1 2E :\ BCM_APP_31381140 AJ \ Read Data By Identifier \
            message.append(text)

    with open('Excel.txt', 'a') as handler:  # create .txt file
        for i in range(len(message)):
            #                  A       B      C     D           E
            handler.write(f"{file}|{date[i]}|{i}|{test[i]}|{response[i]}")
        # A = filename  B = create time  C = number in file  D = tester   E = Complete response

# open with 'w' to "reset" the file.
with open('Excel.txt', 'w') as file_handler:
    pass
# ---------------------------------------------------------------------------------

for filename in glob.glob(r'C:\Users\Desktop\Access\*.log'):
    logfile(filename, 'Sending Request: Tester ->', 'Create Time:','Complete Response:','Channel')


def if_number(s):   # look if number or float
    try:
        float(s)
        return True
    except ValueError:
        return False
# ----------------------------------------------

my_path = r"C:\Users\Desktop\Access"  # directory
# search directory for .txt files
text_files = [join(my_path, f) for f in listdir(my_path) if isfile(join(my_path, f)) and '.txt' in f]

for text_file in text_files:     # loop and open .txt document
    with open(text_file, 'r+') as wordlist:
        string = []  # array ot the saved string
        for word in wordlist:
            string.append(word.split('|'))   # put word to string array
        column_list = zip(*string)  # make list of all string

    workbook = xlwt.Workbook()
    worksheet = workbook.add_sheet('Tab')
    worksheet.col(0)    # construct cell
    first_col = worksheet.col(0)
    first_col.width = 256*50

    second_col = worksheet.col(1)
    second_col.width = 256*25
    third_col = worksheet.col(2)
    third_col.width = 256*10
    fourth_col = worksheet.col(3)
    fourth_col.width = 256*50
    fifth_col = worksheet.col(4)
    fifth_col.width = 256*100

    i = 0   # choose column 0 = A, 3 = C etc
    for column in column_list:

        for item in range(len(column)):
            value = column[item].strip()
            if if_number(value):

                worksheet.write(item, i, float(value))  # text / float
            else:
                worksheet.write(item, i, value)  # number / int
        i += 1

print('File:', text_files, 'Done')

workbook.save(text_file.replace('.txt', '.xls'))

enter image description here

有没有办法自动化“复制粘贴”命令,如果是这样,它会是什么样子和工作?如果那是不可能完成的事情,一些建议会有很大帮助!

修改

谢谢我做了som谷歌搜索并感谢您的帮助!但现在我得到一个错误...我仍然无法将信息发送到Access文件,我收到语法错误。我知道它存在是因为我想要更新现有的文件...是否有一个命令“uppdate exising Acces file”?

错误

pyodbc.ProgrammingError: ('42S01', "[42S01] [Microsoft][ODBC Microsoft Access Driver] Table 'tblLogfile' already exists. (-1303) (SQLExecDirectW)")

import pyodbc


UDC = r'C:\Users\Documents\Access\UDC.accdb'
# DSN Connection
constr = " DSN=MS Access Database; DBQ={0};".format(UDC)
# DRIVER connection
constr = "DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};UID=admin;UserCommitSync=Yes;Threads=3;SafeTransactions=0;PageTimeout=5;MaxScanRows=8;MaxBufferSize=2048;FIL={MS Access};DriverId=25;DefaultDir=C:/USERS/DOCUMENTS/ACCESS;DBQ=C:/USERS/DOCUMENTS/ACCESS/UDC.accdb"

# Connect to database UDC and open cursor
db = pyodbc.connect(constr)
cursor = db.cursor()

sql = "SELECT * INTO [tblLogfile]" +\
      "FROM [Excel 8.0;HDR=YES;Database=C:/Users/Documents/Access/Excel.xls.[Tab];"

cursor.execute(sql)
db.commit()

cursor.close()
db.close()

2 个答案:

答案 0 :(得分:1)

首先,请注意,MS Access是一个数据库管理系统,它不是MS Excel,一个电子表格应用程序。 Access位于关系引擎之上,并且在数据和关系完整性方面保持严格的规则,而在Excel中,任何东西都可以在没有规则的单元格或单元格范围内写入。此外,Access对象库(tabledef,querydef,表单,报表,宏,模块)与Excel对象库(工作簿,工作表,范围,单元格等)有很大不同,因此没有一对一的翻译在代码中。

具体来说,对于您的Python项目,请使用生成表查询来考虑 pyodbc ,该查询运行与Excel工作簿的直接连接。由于MS Access'数据库是ACE / JET引擎(Windows .dll文件,无论是否安装Access,都可在Windows机器上使用)。此数据存储的一个功能是能够连接到工作簿甚至文本文件!实际上,MSAccess.exe只是一个用于查看.mdb / .accdb文件的GUI控制台。

下面创建一个新的数据库表,复制特定的工作簿工作表数据,假设工作表维护:

  1. A1单元格开头的表格格式(无合并单元格/重复标签)
  2. 顶部行中的
  3. 标题(前后没有空格或特殊字符!#$%^~<>))
  4. 一致数据类型格式的列(即数据完整性规则)
  5. Python代码

    import pyodbc
    
    databasename = 'C:\\Path\\To\\Database\\File.accdb'
    
    # DSN Connection
    constr = "DSN=MS Access Database;DBQ={0};".format(databasename)    
    # DRIVER CONNECTION
    constr = "DRIVER={{Microsoft Access Driver (*.mdb, *.accdb)}};DBQ={0};".format(databasename)
    
    # CONNECT TO DATABASE AND OPEN CURSOR
    db = pyodbc.connect(constr)
    cur = db.cursor()
    
    # RUN MAKE-TABLE QUERY FROM EXCEL WORKBOOK SOURCE
    # OLDER EXCEL FORMAT
    sql = "SELECT * INTO [myNewTable]" + \
          " FROM [Excel 8.0;HDR=Yes;Database=C:\Path\To\Workbook.xls].[SheetName$];"
    
    # CURRENT EXCEL FORMAT
    sql = "SELECT * INTO [myNewTable]" + \
          " FROM [Excel 12.0 Xml;HDR=Yes;Database=C:\Path\To\Workbook.xlsx].[SheetName$];"
    
    cursor.execute(sql)
    db.commit()
    
    cur.close()
    db.close()
    

答案 1 :(得分:0)

几乎可以肯定上面Parfait的答案是一个更好的方法,但为了好玩,我会将答案留在下面

如果您愿意花时间我认为您需要3件事来完成您想要做的事情的自动化:

1)将数据的字符串表示形式发送到Windows剪贴板
有特定于Windows的代码,或者您可以节省一些时间并使用pyperclip

2)学习VBA并使用VBA从剪贴板中获取字符串并进行处理。下面是我在Excel中使用的一些示例VBA代码,用于从剪贴板中获取文本

Function GetTextFromClipBoard() As String
    Dim MSForms_DataObject As New MSForms.DataObject
    MSForms_DataObject.GetFromClipboard
    GetTextFromClipBoard = MSForms_DataObject.GetText()
End Function

3)使用pywin32(我相信可以轻松使用Anaconda)来自动化来自Python的vba访问调用。这可能是最困难的部分,因为特定的调用树(在我看来)没有很好的文档记录,需要大量的挖掘和挖掘来弄清楚你究竟需要做什么。至少可以说是痛苦的,但是使用IPython来帮助你了解pywin32对象可用的方法的可视提示。

当我查看上面的说明时,我意识到也可以跳过剪贴板并直接从python发送信息以通过pywin32访问。但是,如果您执行剪贴板路由,则可以中断步骤。

  1. 将一个数据集发送到剪贴板
  2. 抓取并处理数据using the VBA editor in Access
  3. 找出1和2之后,使用pywin32弥补差距
  4. 祝你好运,如果你想出来分享细节,可能会写一篇关于它的博客文章。