`
datamachine
  • 浏览: 156748 次
社区版块
存档分类
最新评论

条件查询大文本文件的通用办法

阅读更多

在进行文本处理时,经常会遇到对大文件进行条件查询的情况。用命令行的grep\cat可以处理一些简单情况,写法很简单,但效率太低,用高级语言处理此类问题虽然可以获得较高的运行效率,但代码编写复杂度却相当高。如果遇到条件比较复杂或条件经常变化的情况,还需要额外实现一套类SQL的底层库函数,其难度会更大。

集算器支持大文件条件查询和多线程并行计算,代码简洁性能优异,下面通过例子来看一下具体作法。

文本文件employee.txt中保存了员工数据。现在要读取员工信息,从中找出198111日(含)之后出生的女员工,最后将查询结果输出到result.txt中。

         文本文件empolyee.txt的格式如下:

EID   NAME       SURNAME        GENDER  STATE        BIRTHDAY        HIREDATE         DEPT         SALARY

1       Rebecca   Moore      F       California 1974-11-20       2005-03-11       R&D          7000

2       Ashley      Wilson      F       New York 1980-07-19       2008-03-16       Finance    11000

3       Rachel      Johnson   F       New Mexico     1970-12-17       2010-12-01       Sales         9000

4       Emily         Smith        F       Texas        1985-03-07       2006-08-15       HR    7000

5       Ashley      Smith        F       Texas        1975-05-13       2004-07-30       R&D          16000

 

集算器代码:



    
A1:以游标的形式打开文件。函数cursor并不会将数据全部读入内存,而是以游标(流)的方式打开文件,因此不会占据内存空间。函数cursor使用了默认参数,即:以tab为列分割符读入全部的字段。选项@t表示文件的第一行是列名,之后可以使用直观的列名来书写表达式,如果没有这个选项,则会自动命名为_1_2_3…_n

A2=A1.select(${where})

按照条件过滤。这里使用宏来实现动态解析表达式,其中的where就是动态传入的参数,需要提前定义。定义参数的界面如下:



 

集算器会先计算${…}里的表达式,将计算结果作为宏字符串值替换${…}之后解释执行。比如按照案例中的条件给where赋值为BIRTHDAY>=date(1981,1,1) && GENDER=="F",则A2的表达式会被替换为=A1.select(BIRTHDAY>=date(1981,1,1) && GENDER=="F")。参数可以在IDE中输入,也可以来自JAVA代码和命令行。

A3=file("D:/result.txt").export@t(A2)将计算结果输出到文件中。如果计算结果总是很小,也可以用=A2.fetch()将计算结果放入内存并直接观察,或者用result A2.fetch()将计算结果返回给JAVA程序。

本案例的最终结果如下:



 
         本案例实现的是动态查询,即过滤条件发生变化时不用改变代码,只需改变where参数即可。例如,条件变为:查询198111日(含)之后出生的女员工,或者NAME+SURNAME等于”RebeccaMoore”的员工。Where的参数值可以写为:BIRTHDAY>=date(1981,1,1) && GENDER=="F" || NAME+SURNAME=="RebeccaMoore"。执行之后,A2中的结果集如下图:



 
前面的算法是串行,改成并行可以进一步提高性能,具体做法是用多个线程并行读取文件,每个线程都用游标访问文件的一部分,并同时进行条件查询,最后再将每个游标的结果合并。

集算器并行计算的代码如下:



     
A1=4A1是分段数量,即将文件分成4段。分段数量,也就是实际执行时的并行数,一般不要超过CPU的核数,否则会形成排队等待,并不能提高性能。实际使用最大并行数量可以在选项中配置。

A2=A1.(file("d:/employee.txt").cursor@z(;, ~:A1))

上面的代码按照分段数量生成4个游标。其中A1.(express)表示按照括号内的表达式依次计算A1的成员,括号内可用“~”来表示当前成员。A1一般是集合,比如["file1", " file2"][2,3]A1如果是从1开始的连续数字,比如[1,2,3,4],则可以简写成4.( express),案例中的代码就是这种情况。

括号内的表达式是file("d:/employee.txt ").cursor@z(;, ~:A1),其中函数cursor使用了选项@z,这表示将文件分段,用游标取其中的某一段。~:A1表示文件会被大致分为4(A1=4),当前取第~段。“~”是A1的当前成员,因此每个游标依次对应第1、第2、第3、第4段文件。

另外,之所以是“大致分”,是因为精确分会出现半行数据的情况,而集算器会去头补位,自动取出整行数据。

A3=A2.(~.select(${where}))这句代码针对A2中的每个游标(即~)进行计算,求查询出游标中符合条件的行数据。这里的计算结果仍然是四个游标。

A4=A3.conj@xm()这句代码将A3中的多个游标进行并行合并。

A5=file("d:/result.txt”).export(A4),将最终计算结果输出到文件中。      

 

  • 大小: 15 KB
  • 大小: 20.7 KB
  • 大小: 14.7 KB
  • 大小: 23.9 KB
  • 大小: 23.2 KB
0
1
分享到:
评论

相关推荐

    补丁模块(带源码)InlinePatch,Hook,内存DLL注入等等

    子程序 打开多文件对话框, 文本型, 公开, 如果多选文件,返回文件路径以“;”(半角分号)分隔。失败或取消返回空文本。 .参数 窗口句柄, 整数型, 可空, 调用处窗口句柄 .参数 窗口标题, 文本型, 可空, 对话框窗口标题...

    C#编程经验技巧宝典

    88 <br>0136 如何进行文本加密与解密 88 <br>0137 如何区别0、空字符串、Null、Empty和Nothing 89 <br>0138 从字符串中分离文件路径、文件名及扩展名 89 <br>0139 如何批量替换某一类字符串 89...

    excel的使用

    我们还可以通过使用条件测试,添加描述文本和使用颜色来扩展自定义格式通用模型的应用。(1)使用颜色 要在自定义格式的某个段中设置颜色,只需在该段中增加用方括号括住的颜色名或颜色编号。Excel识别的颜色名为:...

    Word智能书签插入工具

    这样工作量就相当大,并且可能需要很多人配合去检查数据表格或者调整表格格式,为解决这个问题,本人就想到有没有一种更简单的办法,因此累计花了三四天的时间诞生了这个智能书签插入工具。一般我们搞开发的时候用到...

    O2O掌上城市(ShopNC本地生活).rar

    同时您可能需要一个简单的文本文件编辑软件, 用以对配置文件进行参数修改,一般的第三方软件如 UltraEdit、EditPlus 等都能胜任。ShopNC电商门户系统要求 使用 FTP 软件上传 php 文件时,使用二进制(BINARY)...

    Qt Creator 的安装和hello world 程序+其他程序的编写--不是一般的好

    11.我们双击文件列表的dialog.ui 文件,便出现了下面所示的图形界面编辑界 面。 12.我们在右边的器件栏里找到Label 标签器件 13.按着鼠标左键将其拖到设计窗口上,如下图。 14.我们双击它,并将其内容改为helloworld...

    《你必须知道的495个C语言问题》

    3.18 需要根据条件把一个复杂的表达式赋给两个变量中的一个。可以用下面这样的代码吗?((condition) ? a : b)= complicated_expression; 41  3.19 我有些代码包含这样的表达式。a ? b=c : d 有些编译器可以接受...

    你必须知道的495个C语言问题

    3.18 需要根据条件把一个复杂的表达式赋给两个变量中的一个。可以用下面这样的代码吗?((condition)?a:b)=complicated_expression; 3.19 我有些代码包含这样的表达式。a?b=c:d有些编译器可以接受,有些却不能。为...

    powerbuilder

    参数printjobnumber:用PrintOpen()函数打开的打印作业号string:string类型,指定要打印的文本x:integer类型,指定文本开始打印位置的x坐标,以千分之一英寸为单位y:integer类型,指定文本开始打印位置的y坐标,...

    PHP基础教程 是一个比较有价值的PHP新手教程!

    因此你必须有办法将两者区别开来。以下就是你可以采用的几种方法。你可以选用其中一种你最适应的并且就这样坚持这种方法! 从HTML中分离 以下是可以使用的方法: <script language="php"> . . . 语句 与Perl...

    基于SIP开发软件电话的一些资源(转自YOUTOO)

    直接编译(工程设置里照前文方法在link选项里增加osip2.lib,osipparser2.lib引用我们之前成功编译得到的静态库文件)就可以运行(带参数运行,参数一般为一个文本文件,同样从Test目录的res目录里拷一个与源文件同名...

Global site tag (gtag.js) - Google Analytics