在将日志文本解析成结构化数据时时,常会遇到记录由数量不定的多行组成的情况。这种变换存在一定的复杂性,实现复杂度较高。集算器支持正则表达式、字串拆分、隔行取数、横向拼接等灵活的结构化计算函数,适合处理此类文本。下面通过例子来看一下具体作法。
日志文件reportXXX.log存储着若干记录,每条记录由多行构成,包括14个数据项(字段)。记录以字符串“Object Type”开头。我们的目标是把该日志整理为结构化数据,并将结果写入文本文件。部分源数据如下:
集算器代码:
A1=file("e:\\reportXXX.log").read()
这句代码用来将日志文件全部读入内存,结算结果如下:
A2=A1.array("Object Type: ").to(2,)
这句代码可以分解为两部分。第一部分:将A1按照”Object Type”分割为多个字符串,代码为A1.array("Object Type: "),计算结果如下:
第一条数据无用,之后的每条数据都是一条有效记录,to(2,)表示取出第二条直至最后一条数据。A2的计算结果如下:
A3= regex(正则表达式;字段名列表),这句代码对A3中的每个成员应用同样的正则表达式,并取出14个字段,字段名以逗号分割。下面列出计算结果中的前几个字段:
A4=file("e:\\result.txt").export@t(A3)
上面的代码用来将计算结果写入文件,默认的分割符是tab,选项@t表示将字段名做为文件的第一行。打开result.txt,可以看到下面的数据:
上面代码的正则表达式有些复杂难懂,如果想更直观地解决问题,也可以使用集算器的内置函数。比如:ObjectType字段其实是每条记录的第一行,因此可以先将每条记录按照换行符分,再取第一行。再比如left\top\right\bottom其实是将每条记录的第2行按照空格分割,分别取出第3、5、7、9项。
下面用集算器内置函数来解决本案例:
上述代码中,函数pjoin可将多个集合横向拼接起来,函数array可将字符串按指定分隔符分成多段,并形成一个集合,其中(~.array("\r\n")表示对每条记录按照回车换行拆分。
在前面的案例中,我们假设文件比较小,可以全部读入内存计算,但有时日志文件太大,必须分批读取,分批解析,分批写入文件,开发难度因此会显著提高。由于记录的行数不定,一批数据中总会出现半条记录的情况,处理起来会更加复杂。
集算器支持文件游标,适合处理这类不定行的大日志,代码如下:
A1=file("\\reportXXX.log").cursor@s()
这句代码以游标的方式打开日志文件。函数cursor表示根据文件对象返回游标对象,默认分隔符是tab,默认列名是_1,_2…_n。选项@s表示忽略分割符并将文件内容读成单列字符串,列名是_1。值得注意的是,这句代码只是建立游标对象,并没有读入数据,实际的读入动作会在遇到语句for或函数fetch时触发。
A2: for A1,10000
A2是个循环语句,表示每次从A1读入一批数据(10000行)并送入循环体,直到日志末尾。可以看到,集算器使用直观的缩进来表示循环体,而不是括号或begin/end等标识符。B3-B7就是A2的循环体,其处理过程是:将当前批次的数据按照回车换行符还原成文本,再按照“Object Type:”重新拆分成记录,将最后一条不完整的部分存储在临时变量B1中,并删除第一条和最后一条无用的记录,对剩下的每条记录进行正则表达式解析,形成的二维表追加到文件result.txt中。下面看详细说明:
B2=B1+A2.(_1).string@d("\r\n")
这句代码将临时变量B1和当前批次的文本拼在一起。第一次循环时B1为空,以后每次循环时B1会存储上个批次的半条记录,B1和当前批次的文本拼在一起,就会使半条记录变完整。
函数string可以把集合成员按照指定的分割符拼成一个大字符串,选项@d表示不在成员的两边加引号。比如第一次循环时,A2的前几行为:
A2.(_1)表示A2的字段_1形成的集合,即:
A2.(_1).string@d("\r\n")表示将上述集合拼成一个大字符串,即:Object Type: Symbol Location: left: 195 top: 11 right: 123 bottom: 15 Line Color: RGB ( 1 0 0 ) Fill Color: RGB ( 251 255 0 ) Link:l11….
B3=B2.array("Object Type: ")
这句代码将B2中的大文本按照“Object Type”分割为多个字符串。B3在第一次循环时计算结果如下:
由于B3中的最后一个字符串往往只有记录的一部分,无法参与完整计算,应该将它存在临时变量中,下次循环时再把它和新批次的字符串拼在一起。B4中的代码可以将该字符串存入临时变量B1。
B4=B1="Object Type: "+B3.m(-1)+"\r\n"
函数m表示正向或逆向取集合中的成员,取第一个可以写作m(1),取前三个写作m([1,2,3]),倒数第一个写作m(-1)。也可以直接用B3(1)来正向取第一个成员。另外,前面字符串拆分时已经去掉了每条记录开头的“Object Type”,所以这里要恢复原样。从cursor按行读文件时会去掉回车换行,这里补一个“\r\n”。
B3的第一个成员是空行,最后一个成员是半条记录,这两行都无法参与计算,可以使用下面的代码删除这两个成员:
B5=B3.to(2,B3.len()-if(A1.fetch@0(1),1,0)))
这句代码用来取出B3中的有效数据。如果当前批次不是最后一批,则第一条是空记录,最后一条是半条记录,应当取出第二条直至倒数第二条。如果当前批次是最后一批,则第一条是空记录,最后一条是完整记录,应当取出第二条直至最后一条。
函数B3.to(m,n)表示取出B3中序号在m和n之间的记录。B3.len()表示B3的记录数,相当于当前批次最后一条记录的序号。A1.fetch(n)表示取出游标A1中的n条行,选项@0表示只查看数据,游标位置并不移动。函数if有三个参数,分别是布尔表达式、表达式为true时返回的结果、表达式为false返回的结果。当前批次不是最后一批时,A1.fetch@0(1)为有效记录,函数if返回1;当前批次是最后一批时,A1.fetch@0(1)为空,函数if返回0。
B6=B5.regex(正则表达式;字段名列表),这句代码对B5中的每个成员应用同样的正则表达式,并取出14个字段,字段名以逗号分割。下面列出计算结果中的前几个字段:
B7=file("e:\\result.txt").export@a(B6)
这句代码将B6追加到result.txt中,每次循环追加一批记录,直到日志结尾。打开大文件result.txt可以看到本案例的最终计算结果:
上述算法中在循环中进行正则表达式解析,但正则表达式的编译性能较差,尽量不要在循环中使用,这时可以使用两个集算器脚本配合函数pcursor来实现流式分拆和解析。
首先是主程序main.dfx,代码如下:
函数pcursor调用了一个子程序,用来返回单列记录形成的游标。A2格对A1中的每条记录进行正则表达式解析,返回结构化数据。注意:A2的计算结果是游标,而不是内存中的数据,执行函数export时,游标A2才会被分批读入内存并进行计算,而这个分批的动作是自动完成的。
子程序sub.dfx的作用是返回游标,写法和前面的案例类似,不同之处是:无需写文件,直接返回单列记录,如下:
B6中的result可以将B5转为单列序表,并以游标的形式返回给调用者(main.dfx中的函数pcursor)。
通过函数pcursor,主程序main.dfx可以将子程序sub.dfx当做普通游标来取数,而不用管数据的生成过程。Main.dfx需要数据的时候,pcursor函数会根据缓冲区剩余的数据来判断是否继续执行sub.dfx中的循环,或是从缓冲区直接返回数据,整个过程自动完成。
相关推荐
### 结构化文本(ST)编程知识点解析 #### 一、结构化文本(ST)简介 结构化文本(Structured Text, ST)是一种基于文本的高级编程语言,它为可编程逻辑控制器(PLC)提供了一种类似于高级语言的编程方式。这种语言...
"PLC结构化文本编程" PLC结构化文本编程是一种基于文本语言的编程方式,用于编程可编程逻辑控制器(PLC)。这种编程方式具有高灵活性和可维护性,适合复杂控制系统的开发。 知识点1:PLC的基本概念 PLC是一种工控...
《日志服务数据加工:非结构化数据解析实践》 日志服务是针对日志分析领域的一款强大工具,它的核心功能在于将各种非结构化的日志数据转化为结构化数据,以便进行实时处理、数据仓库计算以及数据分析。日志服务具备...
详解银行非结构化文本数据背后的价值-匠心独运 厚积薄发.pdf
因此,自动化日志解析成为了研究的热点,它旨在将自由文本的日志消息转化为结构化的事件,便于后续的数据挖掘和分析。 现有的日志解析方法虽然在准确性上表现出色,但缺乏开源实现和性能基准对比,导致开发者在实际...
在IT行业中,富文本解析是开发过程中的常见需求,特别是在Web应用、移动应用以及各种内容管理系统中。富文本指的是包含格式化元素(如字体、颜色、大小、图像、链接等)的文本,与纯文本相比,它能提供更加丰富的...
在Android平台上,富文本解析是实现复杂文本展示和编辑的关键技术。富文本解析器能够将HTML和Markdown这两种标记语言转化为可读性强、样式丰富的文本,为用户提供了更佳的视觉体验。本文将深入探讨Android环境下如何...
6. **定时任务调度**: 要实现日志解析和存储的自动化,通常会使用定时任务工具,如Linux系统的cron或Windows的任务计划程序。`modsecurity_log_mysql.py`脚本将被配置为定时运行,确保日志数据定期更新到数据库中。 ...
富文本解析对于微信小程序的意义在于,它能够帮助开发者处理从服务器获取的格式化内容,这些内容通常以HTML或Markdown等形式存在。通过解析,小程序可以正确地显示这些内容,提供更好的用户体验。 二、微信小程序的...
# 这里写正则表达式或其他逻辑来解析日志行 ... with open('E:/nextcloud.log', 'r') as file: log_data = [] for line in file: parsed_line = parse_log(line) log_data.append(parsed_line) df = pd....
在处理结构化文本数据时,理解并熟练运用这些工具,能够极大地提高工作效率,无论是数据分析、日志分析还是自动化任务,都有其独特的价值。在实际工作中,往往需要结合使用多种工具,根据具体需求进行组合和定制,...
介绍什么? 为什么? 如何? 用法安装解析字符集转换常见转换键入标签正向引用语法Sugar White Space Err...消费者是Mac和iOS的库,用于解析结构化文本,例如配置文件或编程语言源文件。 主要接口是消费者类型,用于
文本图谱化,文本解析成图谱表示,包含ner和textrank等技术,应用ltp模型进行ner,将文本转化为echarts.js支持的图谱展示;包含ner和textrank等技术,应用ltp模型进行ner,将文本转化为echarts.js支持的图谱展示;
本教程将探讨如何使用Python来解析EVTX日志,过滤特定事件,并根据IP地址解析出实际的物理地址。 首先,我们需要了解Python中的`xml.etree.ElementTree`库,这是Python标准库的一部分,用于处理XML数据。EVTX文件...
1. **日志预处理**:首先,对原始日志进行清洗和标准化,去除噪声和无关信息,准备后续的分析。 2. **单词分类**:利用机器学习算法,如深度学习模型,对日志中的每个单词进行分类,判断其是否属于模板部分还是可变...
结构化日志记录,正如“日志:结构化日志记录解决方案”这个标题所指,是一种将日志信息以统一格式和结构存储的方法,使得日志数据更易于解析、分析和检索。在本文中,我们将深入探讨结构化日志记录的重要性、实现...
地址结构化要素解析是指将非结构化的地址文本转换为结构化的数据格式的过程。这一过程对于提高各种服务的效率至关重要,例如快递服务、外卖配送、地图导航等领域都需要对地址进行精准的解析来提高服务质量和效率。 ...
SR(Structured Report)是DICOM标准中的一个重要部分,它允许医生和其他医疗专业人员以结构化的形式记录和交换临床观察结果,如诊断报告、检查结果等。这种结构化的数据便于信息的检索、分析和整合到电子健康记录中...