文本分组计数
【问题】
45 a
36 a
58 a
21 a
31 b
12 b
23 b
21 c
32 c
45 c
…
这是我的文件格式,我要先计算带有a的行数,写在输出文件的第一行,再把带有a的行写在下面,之后再写带b的行,再写带c的行。输出文件是下面的格式:
a 4
45
36
58
21
b 3
31
12
23
c 3
21
32
45
…
我现在是先读一遍源文件,计算出带
a
、
b
、
c
各自的行数,写在一个临时文件里,然后再重新读一遍源文件,同时读临时文件,再写到输出文件中。
我总觉得这样很繁琐,不知道有没有简便的方法,读一次源文件就可以实现?
【回答】
这就是简单的分组汇总,高级语言缺乏这类SQL式计算的类库,直接针对文本文件编写非常麻烦,建议采用SPL,写法要简单许多
如果文件不大(可装入内存),只要读一遍即可,代码如下:
A |
B |
|
1 |
=file("E:\\source.txt") |
=file("E:\\result.txt") |
2 |
=A1.import().group(_2) |
|
3 |
for A2 |
>B1.write@a(A3._2+"\t"+string(A3.len())) |
4 |
>B1.export@a(A3,_1) |
A1、B1:打开指定文本文件。
A2:读取文件source.txt,并按照第2列分组排序。
A3-B4循环A2,针对A2每个分组(即A3)统计成员个数,并生成一条记录追加写入到result.txt,最后将A3追加导入到result.txt。
如果文件太大(内存装不下),就需要用到临时文件了,不过已经被SPL 封装过了,代码几乎一样:
A |
B |
|
1 |
=file("E:\\source.txt") |
=file("E:\\result.txt") |
2 |
=A1.cursor().sortx(_2) |
|
3 |
for A2;_2 |
>B1.write@a(A3._2+"\t"+string(A3.len())) |
4 |
>B1.export@a(A3,_1) |
A1、B1:打开指定文本文件。
A2:将文件source.txt读成游标,并按照第2列排序,其中sortx会产生临时文件,把排序结果暂存起来。
A3-B4循环A2,每次从A2读取部分记录至第2列值有变化,并生成一条记录追加写入到result.txt,最后将A3追加导入到result.txt。