[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[文本处理] 【已解决】批处理:如何批量提取多个文本内出现次数最多、次多与再次多的数据

本帖最后由 思想之翼 于 2014-8-29 00:24 编辑

问题1:
“文件夹1”内有210个txt文本,分别命名为001、002...210,每个txt文本记录若干数据,欲批量提取各文本数据出现次数最多的数据,并写入“文件夹2”的001.txt 002.txt ...210.txt
比如  附件“文件夹1”内001.txt中,出现最多次数(都是35次)的数据是76  54  38,提取出来并写入“文件夹2”的001.txt
上述问题的解决代码是:
  1. @echo off
  2. cd /d "e:\123\文件夹1"
  3. for %%i in (*.txt) do (
  4.     setlocal enabledelayedexpansion
  5.     for /f "delims=" %%a in (%%i) do (
  6.         for %%b in (%%a) do (
  7.             set/a #%%b+=1
  8.             if !#%%b! gtr !max! (
  9.                     set/a max=!#%%b!
  10.                     set "#=%%b"
  11.             ) else if !#%%b! equ !max! set "#=!#! %%b"
  12.         )
  13.     )
  14.     echo,!#!>"e:\123\文件夹2\%%i"
  15.     endlocal
  16. )
复制代码
问题2:
问题1是:提取出现最多次数的数据。
如果提取出现最多次多次数的数据,代码将如何修改?
如果提取出现最多次多再次多次数的数据,代码将如何修改?
附件: 您需要登录才可以下载或查看附件。没有帐号?注册

本帖最后由 apang 于 2014-8-28 10:36 编辑

更改第2行x的值
  1. @set @n=0;/* & echo off
  2. set "x=3"
  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.     txt = fso.OpenTextFile(f, 1).ReadAll();
  11.     txt = getMaxNum(txt, WScript.Arguments(0));
  12.     txt = txt.replace(/^\d+ /mg, "");
  13.     fso.CreateTextFile("..\\文件夹2\\"+f, true).Write(txt);
  14. }
  15. function getMaxNum(str, arg) {
  16.     dic = new ActiveXObject("Scripting.Dictionary");
  17.     for (i=100; i<=199; i++) {
  18.         num = (i + "").substr(1);
  19.         k = str.split(num).length;
  20.         if (k > 1) {
  21.             if (dic.Exists(k)) {
  22.                 dic.Item(k) += " " + num
  23.             } else dic.Add(k, k + " " + num)
  24.         }
  25.     }
  26.     arItem = (new VBArray(dic.Items())).toArray();
  27.     s = "";
  28.     arItem.sort(function(x,y) {return y.split(" ")[0]-x.split(" ")[0]});
  29.     if (arg > arItem.length) arg = arItem.length;
  30.     for (i=0; i<arg; i++) {
  31.         s += arItem[i] + "\r\n";
  32.     }
  33.     return s
  34. }
复制代码
1

评分人数

TOP

回复 2# apang
感谢您的帮助!
代码圆满解决问题。只有一点遗憾:
因为不知道有多少重复次数,如果第二行设置不当,比如set "x=100"
就会出现如下结果
38 54 76
29 97
08 57
07 12 83
45 71
03 31 63 65 67
11 32 35 44 48 56 66 74 80 93 94
21 25 51 58
04 39 40 42 64 73 75 98
06 15 19 27 36 59 68 69 86
05 09 17 20 24 52 55 72 78 91 96
13 16 18 49 60 77 79 81 89 90 92
01 22 26 34 50 62 87 88
14 23 41 70 82
02 28 43 47 95
30 33 37 84
46 53 85
61
10
00
99
undefined
undefined
undefined
......
undefined
如何才能不显示undefined?

TOP

回复 3# 思想之翼


    在37和38行之间插入一行:
  1. if (arg > ar.length) arg = ar.length
复制代码
1

评分人数

TOP

回复 4# apang
谢谢帮助!
经过测试,加上这句代码,结果出现偏差,请见附件,原本结果是:
29 59
79 98
11
26 68
32
03 42
82
33 45 50 57
08 23 37 62 69
12 30 31 49 55 63 66 74 87
04 44 48 73 77 93
02 36 39 58 61 71
09 14 18 60 84
05 15 16 19 20 27 34 43 76
01 07 22 72
06 13 24 52 65 67 75 91
21 35 47 81 85 88
25 46 51 80 83 86 96
10 17 56 94
41 53 89
64 78 95
70 97
28 40
92
90
38
00
99
undefined
...
undefined

加上判断的代码,结果是:
29 59
79 98
11
26 68
32
03 42
82
33 45 50 57
08 23 37 62 69
12 30 31 49 55 63 66 74 87
04 44 48 73 77 93
02 36 39 58 61 71
09 14 18 60 84
05 15 16 19 20 27 34 43 76
01 07 22 72
06 13 24 52 65 67 75 91
21 35 47 81 85 88
25 46 51 80 83 86 96
10 17 56 94
41 53 89
64 78 95

少了:
70 97
28 40
92
90
38
00
99
附件: 您需要登录才可以下载或查看附件。没有帐号?注册

TOP

回复 5# 思想之翼


    2#已修改

TOP

回复 2# apang
感谢您的帮助!
如果文本001.txt为空,运行该代码得不到任何文本。实际运用中,需要输出一个名称为001.txt的空文本。有劳您再费神了,谢谢!

TOP

回复 7# 思想之翼


好吧,以后请把要求一次性说清楚
  1. @set @n=0;/* & echo off
  2. set "x=3"
  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=100; i<=199; 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, k + " " + num)
  25.         }
  26.     }
  27.     arItem = (new VBArray(dic.Items())).toArray();
  28.     s = "";
  29.     arItem.sort(function(x,y) {return y.split(" ")[0]-x.split(" ")[0]});
  30.     if (arg > arItem.length) arg = arItem.length;
  31.     for (i=0; i<arg; i++) {
  32.         s += arItem[i] + "\r\n";
  33.     }
  34.     return s.replace(/^\d+ /mg, "")
  35. }
复制代码
1

评分人数

TOP

回复 8# apang
这里的最后取值 直接取 Item 是否简洁点呢 这样的话 排序也就直接排序了

TOP

本帖最后由 apang 于 2014-9-1 19:12 编辑

回复 9# terse


    请教terse,如何直接取Item值呢?
上面确实绕弯了
  1. function getMaxNum(str, arg) {
  2.     dic = new ActiveXObject("Scripting.Dictionary");
  3.     for (i=100; i<=199; i++) {
  4.         num = (i + "").substr(1);
  5.         k = str.split(num).length;
  6.         if (k > 1) {
  7.             if (dic.Exists(k)) {
  8.                 dic.Item(k) += " " + num;
  9.             } else dic.Add(k, num)
  10.         }
  11.     }
  12.     ar = (new VBArray(dic.Keys())).toArray();
  13.     s = "";
  14.     ar.sort(function(x,y){return y-x});
  15.     if (arg > ar.length) arg = ar.length;
  16.     for (i=0; i<arg; i++) {
  17.         s += dic(ar[i]) + "\r\n";
  18.     }
  19.     return s
  20. }
复制代码
1

评分人数

TOP

返回列表