Board logo

标题: [其他] 【已解决】文本记录数值庞大,如何实现按出现次数排序 [打印本页]

作者: 思想之翼    时间: 2023-6-26 17:28     标题: 【已解决】文本记录数值庞大,如何实现按出现次数排序

本帖最后由 思想之翼 于 2023-6-30 15:43 编辑

下述代码将文本记录数值,按出现次数排序:
331 445 550 567
008 023 327 550 689
142 350 331 449 550 653
结果为:
550 (出现3次)
331 (出现2次)
445 550 567 008 023 327 689 142 350 449 653 (出现1次)
  1. @set @n=0;/* & echo off
  2. set "x=1000"
  3. md "文件夹2" 2>nul
  4. pushd "文件夹1\"
  5. dir /b *.txt|cscript -nologo -e:jscript "%~0" "%x%"
  6. pause & exit/b & rem */
  7. fso = new ActiveXObject("Scripting.FileSystemObject");
  8. while (!WScript.StdIn.AtEndOfStream) {
  9.     f = WScript.StdIn.ReadLine();
  10.     try {
  11.         txt = fso.OpenTextFile(f, 1).ReadAll();
  12.         txt = getMaxNum(txt, WScript.Arguments(0));
  13.     } catch(e) { txt = "" }
  14.     fso.CreateTextFile("..\\文件夹2\\"+f, true).Write(txt);
  15. }
  16. function getMaxNum(str, arg) {
  17.     dic = new ActiveXObject("Scripting.Dictionary");
  18.     for (i=1000; i<=1999; i++) {
  19.         num = (i + "").substr(1);
  20.         k = str.split(num).length;
  21.         if (k > 1) {
  22.             if (dic.Exists(k)) {
  23.                 dic.Item(k) += " " + num;
  24.             } else dic.Add(k, num)
  25.         }
  26.     }
  27.     ar = (new VBArray(dic.Keys())).toArray();
  28.     s = "";
  29.     ar.sort(function(x,y){return y-x});
  30.     if (arg > ar.length) arg = ar.length;
  31.     for (i=0; i<arg; i++) {
  32.         s += dic(ar[i]) + "\r\n";
  33.     }
  34.     return s
  35. }
复制代码
问题:若文本记录数值达3GB,该代码出错。
请教:有无其他方法,实现按出现次数排序?
作者: jyswjjgdwtdtj    时间: 2023-6-26 17:57

本帖最后由 jyswjjgdwtdtj 于 2023-6-26 18:10 编辑

你倒是说哪里错了?
想办法把那个readall改了 这么高肯定内存不够
还有既然只用了js为什么还要用bat套一层?纯属有问题
还有js有原生的”对象“为什么还要用dictionary?
作者: 思想之翼    时间: 2023-6-26 18:05

本帖最后由 思想之翼 于 2023-6-26 18:13 编辑

回复 2# jyswjjgdwtdtj

cscript.e×e-应用程序错误
0x000007FFA4A432751指令用了00000000143009000内存。该内存不能为written。
要终止程序,请弹击确定。
作者: jyswjjgdwtdtj    时间: 2023-6-26 18:23

本帖最后由 jyswjjgdwtdtj 于 2023-6-26 19:06 编辑

做了个没能排序的
  1. var fso = new ActiveXObject("Scripting.FileSystemObject");
  2. var f=fso.OpenTextFile("1.txt",1);
  3. var o=fso.CreateTextFile("2.txt",true)
  4. var text="";
  5. var b={};
  6. var c={};
  7. while(!f.AtEndOfStream){
  8. text=f.ReadLine();
  9. for(var s=text.split(" "),l=s.length,i=0;i<l;i++){
  10. b[s[i]]=tn(b[s[i]])+1
  11. }
  12. }
  13. function tn(n){
  14. return(n==undefined?0:+n);
  15. }
  16. for(var i in b){
  17. if(c[b[i]]==undefined) c[b[i]]=[];
  18. c[b[i]].push(i);//b[i]是次数 push的内容是当前次数的值
  19. }
  20. delete b;
复制代码
可以把同个次数的放到一起 但是排序不会
一想到要排序对象搞来搞去的 就觉得脑子要炸了 拜拜
作者: czjt1234    时间: 2023-6-26 19:56

我用vbs调用文本数据库统计了一个2G文件的排序,耗时210秒
惭愧惭愧,就不发出来了

等待第三方软件吧
作者: czjt1234    时间: 2023-6-26 19:58

话说这么大的数据量,居然不用数据库,也真是服了
作者: jyswjjgdwtdtj    时间: 2023-6-26 21:52

回复 5# czjt1234


    第三方软件也没区别吧 直接在c++里面读估计会快很多很多
第一次见到3gb的文本文件
作者: Gin_Q    时间: 2023-6-27 09:14

如果内存够都话,应该不会报错。
作者: Gin_Q    时间: 2023-6-27 09:15

你贴一段文本出来,我用Python试试。不需要太大。我看看文本格式。
作者: hfxiang    时间: 2023-6-27 09:25

回复 1# 思想之翼
没有制备3gb的数据来测试,如下指令用1楼的示例数据测试是有效的
  1. gawk "{for(i=1;i<=NF;i++){if(!a[$i]++)b[++j]=$i;if(0+N<a[$i])N=a[$i]}}END{for(k=1;k<=j;k++)c[a[b[k]]]=c[a[b[k]]]b[k]\" \";s=asorti(c,tA);for(i=s;i>0;i--)print c[tA[i]]}" 1.txt>2.txt
复制代码

作者: 思想之翼    时间: 2023-8-22 05:04

回复 10# hfxiang

感谢!gawk代码单独使用,结果正确。若在如下循环语句中使用,则结果为空。恳望指点。

@echo off
for /l %%f in (1000001,1,1000100) do (
    setlocal enabledelayedexpansion
    set p=%%f
       gawk "{for(i=1;i<=NF;i++){if(!a[$i]++)b[++j]=$i;if(0+N<a[$i])N=a[$i]}}END{for(k=1;k<=j;k++)c[a[b[k]]]=c[a[b[k]]]b[k]\" \";s=asorti(c,tA);for(i=s;i>0;i--)print c[tA]}" d:\!p:~1!\!p:~1!.txt > e:\!p:~1!\!p:~1!.txt
    endlocal
)
exit
作者: 77七    时间: 2023-8-22 07:05

本帖最后由 77七 于 2023-8-22 07:09 编辑

回复 11# 思想之翼


   可能和这个原因是一样的。http://bbs.bathome.net/redirect.php?goto=findpost&ptid=66801&pid=271170
作者: 思想之翼    时间: 2023-8-22 08:06

回复 12# 77七

谢谢!在gawk命令中的 ”!“ 前加个 “^” 转义




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2