【问题】
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。