Board logo

标题: [文件操作] 批处理怎样对多个文本文件的指定数据统计? [打印本页]

作者: dreamboc    时间: 2008-1-27 21:18     标题: 批处理怎样对多个文本文件的指定数据统计?

大家好,最近工作上遇到一件麻烦事啊。问朋友说是用批处理来处理要快一些,但苦于不了解这个,因此特来此请教。
     因为快到春节了,要总结上一年的工作,而07的帐户要处理,问题如下。
有多个文件夹,命名方式如20070101一直到20071231,而每个文件夹里有多个TXT文本文件,其中有一个比如1357.TXT
打开1357.TXT,内容如下,最上边是文档说明,时间类别之类,然后下面就是各种产品交易信息等等
                    比如 1月1日  产品销售统计表,见附件,等等,每天的TXT表格式都是如此。
我想统计销售总金额应该怎么办啊。
针对朋友提出的问题,有两类表,一种是有小数的,一种是没有小数的,有小数的那种有两位有效数字。
我刚刚接手,烦啊。
期待大家指教
如果有能解决的朋友,也请把思路告诉我,日后再碰到类似问题 ,我也好处理啊。
非常感谢
我的邮箱是[email=bluedream5566@126.com]bluedream5566@126.com[/email],若需要详细资料的可以联系我啦。
作者: 随风    时间: 2008-1-27 21:30

1、这些文件夹是否都在同一个文件夹内?
2、最好复制一部分11.txt文件的内容上来。
3、价格含小数吗?如果含小数就不好处理了。
4、统计后的结果如何处理?是都写入到一个新的txt文件内吗?
作者: dreamboc    时间: 2008-1-27 22:14

不在同一个文件夹内,每天一个文件夹,每个文件夹中有一个TXT文本文件,金额大多数都有小数。
现在数据不带在身上,明天发个附件给你吧,谢谢。
作者: dreamboc    时间: 2008-1-27 22:16

最终的统计结果合计到一个TXT文件中
如果方便,留个邮件地址给我可以么,数据不大方便公开
作者: xxx3212    时间: 2008-1-27 22:25

可以调用vbs计算小数
作者: foxJL    时间: 2008-1-27 23:53

复制一段大概的就好了,你可以把操作员和金额改了再发出来,这样就不会泄漏公司的机密了.
作者: dreamboc    时间: 2008-1-28 20:48

活活,上传附件了啊,感谢热心人
作者: foxJL    时间: 2008-1-28 21:11

复制一份文本格式的发出来吧.我们也好复制.
还有:
从20070101到20071231目录都是在一个文件夹里面吗?

你所比如的"1357.TXT"数据文件是不是固定的名字?如果不是那有什么特征来判断哪个文件是数据文件?
作者: dreamboc    时间: 2008-1-28 21:39

******************************************************************************************************************************
*                                                   销售表                                                                       *
******************************************************************************************************************************
                客户帐号      产品代码         公司帐号          交易金额      交易类型         
           =============   =============   ================   ==================                    
                     0691280      012         542660              3,000.00     111
                    1610530      803         616183             20,000.00     111                                          
                    0855230      003         007598             10,000.00     111                                          
                    0211090      001         435238             20,000.00     111                                          
                    0861920      001         561694             12,000.00     111                                          
                    0747690      001         544146             20,000.00     111                                          
                    0800420      803         543999             50,000.00     111                                          
                    0385610      803         266971             10,000.00     111                                          
                    1039860      803         050714             20,000.00     111                                          
                    0956590      005         564250             10,000.00     111
作者: foxJL    时间: 2008-1-28 21:41

因为你还有一些问题没有说清楚,所以按照你上面所描述的,查找每个目录里面的"1357.txt"这个文件,写了一个.
你只需把这个脚本放在20070101目录的上一层就可以了.
  1. @echo off
  2. set nums=0
  3. for /f %%i in ('dir /b /s 1357.txt') do (
  4. for /f "skip=5 tokens=1-4" %%j in (%%i) do (
  5. set num=%%m
  6. call set num=%%num:,=%%
  7. call set num=%%num:.=%%
  8. call set /a nums+=%%num%%
  9. )
  10. )
  11. echo 总交易金额是:%nums:~0,-2%.%nums:~-2%
  12. pause
复制代码

作者: dreamboc    时间: 2008-1-28 21:45

我先去试试看呀,非常感谢
作者: dreamboc    时间: 2008-1-28 21:48

原帖由 foxJL 于 2008-1-28 21:11 发表
复制一份文本格式的发出来吧.我们也好复制.
还有:
从20070101到20071231目录都是在一个文件夹里面吗?

你所比如的"1357.TXT"数据文件是不是固定的名字?如果不是那有什么特征来判断哪个文件是数据文件?


从20070101到20071231都在一个文件夹里面,1357是固定名字,除了周末,每天都生成
作者: foxJL    时间: 2008-1-28 21:51

那应该就没问题了,你测试一下看有没有什么问题,再反馈.
作者: foxJL    时间: 2008-1-28 23:26

根据你给我的数据,增加了一点.
  1. @echo off&setlocal enabledelayedexpansion
  2. set lx=6210,6221,6222
  3. set "6210=认购" && set "6221=申购" && set "6222=赎回"
  4. for %%a in (%lx%) do (
  5. set nums=0
  6. for /f %%i in ('dir /b /s %%a') do (
  7.         for /f "skip=5 tokens=1-4" %%j in (%%i) do (
  8.                 if not "%%j"=="*" (
  9.                         set num=%%m
  10.                         set num=!num:,=!
  11.                         set num=!num:.=!
  12.                         set /a nums+=!num!>nul 2>nul
  13.                         )
  14.                 )
  15.         )
  16. echo !%%a!类型 总交易金额是:!nums:~0,-2!.!nums:~-2!
  17. )
  18. echo.&echo ---统计完成,键任意键退出.&pause>nul
复制代码

[ 本帖最后由 foxJL 于 2008-1-28 23:29 编辑 ]
作者: 梦想种子    时间: 2008-1-28 23:35

因为小数问题,兼用VBS比较方便。
  1. @echo off&setlocal enabledelayedexpansion
  2. set batpath=%~d0%~p0
  3. echo 统计中...
  4. for /f %%i in ('dir /b /ad RPT2007*') do (
  5. cd /d %%i
  6. for /f "delims=" %%j in ('dir /b /s 62*') do (
  7. for /f "skip=5 tokens=4" %%k in ('type "%%j"') do (
  8. set t=%%k
  9. echo !t:,=! >>"%batpath%result.txt"
  10. )
  11. )
  12. cd ..
  13. )
  14. echo dim fso,data,n,sum,h >>cal.vbs
  15. echo set fso=createobject("scripting.filesystemobject") >>cal.vbs
  16. echo set data=fso.opentextfile("result.txt") >>cal.vbs
  17. echo do >>cal.vbs
  18. echo n=data.readline >>cal.vbs
  19. echo if isnumeric(n) then >>cal.vbs
  20. echo n=cdbl(n) >>cal.vbs
  21. echo sum=sum+n >>cal.vbs
  22. echo end if >>cal.vbs
  23. echo loop until data.atendofstream >>cal.vbs
  24. echo data.close >>cal.vbs
  25. echo fso.deletefile("result.txt") >>cal.vbs
  26. echo fso.deletefile "cal.vbs" >>cal.vbs
  27. echo msgbox "总额为:" ^& sum ^& "元。" >>cal.vbs
  28. start cal.vbs
复制代码

作者: dreamboc    时间: 2008-1-28 23:41

收下来,活活。晚安呀,兄弟
作者: namejm    时间: 2008-1-29 00:08

  在DOS联盟里也看到了你的求助帖,在那个帖子里,你最开始还想求出每个操作员的操作次数。其实,用批处理是完全可以办到的。

  从你在顶楼发的数据来看,我并没有找到操作员的信息,姑且把客户帐号当作你想要的操作员吧,现在,我把你的环境做如下假设(若与你的情况不符,请跟帖提出):
  在某个文件夹下(假设是test),只存在从20070101到20071231为名的文件夹,而每个文件夹下,都存在一个1357.txt文件,这个文件存放的是你即将要统计的数据,金额一栏小数点后的两位数字都是0,现在要统计每个操作员的操作次数(在你的数据中,实际上对应的是客户帐号)及总共的金额,那么,可把如下代码放到test目录下运行即可。

  以下代码的总体思路是:先在当前目录及其所有子目录中搜索1357.txt,然后,把所有1357.txt的内容都去掉头5行之后,合并到test.txt中,再对test.txt的内容进行排序,通过比较上下行第一列内容的不同求出客户帐号出现的次数(也就是操作员操作的次数),从而避免了设置大量变量的情况,和DOS联盟3742668的代码比起来,这个方案能够避免产生大量的临时文件:
  1. @echo off
  2. :: 凌晨时发的代码有错误,请用本次代码测试[2008-1-29 17:59]
  3. cd.>test.txt
  4. set /a total=0,times=1
  5. for /f "delims=" %%i in ('dir /a-d /b /s 1357.txt') do (
  6.     >>test.txt more +5 "%%i"
  7. )
  8. setlocal enabledelayedexpansion
  9. for /f "tokens=1,4,5 delims=,. " %%i in ('sort test.txt') do (
  10.     if defined ID (
  11.         if "!ID!"=="%%i" (
  12.             set /a times+=1
  13.         ) else (
  14.             echo !ID! 出现的次数是 !times!
  15.             set times=1
  16.         )
  17.     )
  18.     set /a total+=%%j%%k
  19.     set ID=%%i
  20. )
  21. echo %ID% 出现的次数是 %times%
  22. echo 总金额是 %total%.00
  23. pause
复制代码
  如果只需要统计总金额,那就太容易了:
  1. @echo off
  2. for /f "delims=" %%i in ('dir /a-d /b /s 1357.txt') do (
  3.     for /f "usebackq skip=5 tokens=4,5 delims=,. " %%j in ("%%i") do (
  4.         set /a total+=%%j%%k
  5.     )
  6. )
  7. echo 总金额是 %total%.00
  8. pause
复制代码
  另:你在顶楼发了两个数据附件,但是内容都是一样的,我猜想你是想另传一个不带小数点的数据文件,但是选重了。我删除了其中一个,请把不带小数点的数据文件也发出来,让我们看一下格式吧。
作者: namejm    时间: 2008-1-29 18:12

凌晨时发的第一个代码有错误,请用本次代码测试[2008-1-29 17:59]
作者: dreamboc    时间: 2008-1-29 22:05

原帖由 foxJL 于 2008-1-28 23:26 发表
根据你给我的数据,增加了一点.@echo off&setlocal enabledelayedexpansion
set lx=6210,6221,6222
set "6210=认购" && set "6221=申购" && set "6222=赎回"
for %%a in (%lx%) do (
set nums=0
for /f %%i in ( ...

活活,老乡,谢谢啦
作者: namejm    时间: 2008-2-1 00:23

  楼主给我传了原始数据,并附上了处理要求,本来想通过QQ联系楼主,再进一步确认一些细节,可惜把附件里提到的QQ加上之后,那个QQ的主人说:楼主留的QQ不是楼主的=_=!现把我的代码发出来,楼主看看是否达到你的要求;若需要修改,请跟帖提出;如有必要,请站内短信联系。

  以下代码必须放在 E:\nstpp\rbs 下执行,若盘符有变,不影响结果;若路径的层深有变,则需要修改部分代码:
  1. @echo off
  2. :: 1、搜索所有的数据文件
  3. :: 2、提取所有数据文件中第5行后所有的第一列数据,
  4. :: 3、重组为 "第一列数据 纯数字型文件夹名 纯数字型文件名"的格式(关键)
  5. :: 4、把重组后的数据按照月份写入"根目录\tmp\××\tmp1.txt"文件中
  6. :: 5、把tmp1.txt中的所有帐号内容提取到tmp2.txt中
  7. :: 6、对tmp2.txt中的数据进行统计,按照
  8. :: "帐户号      月份 总数" 或者
  9. :: "帐户号 月份数 类型号 小计数" 的格式导入"根目录\tmp\tmp_月份号.txt"中
  10. :: 7、按格式提取统计信息
  11. :: 关键处有两点:1、重新组合相关数据并分类写入相关文件;2、各种相似数据的累加
  12. rem ==========初始化各种设置=============
  13. set begin=%time%
  14. set root=%cd:~0,2%
  15. set FileNum=0
  16. :: 统计脚本所在目录存在的文件数量,为后面的 skip=%FileNum% 提供数据
  17. for /f %%i in ('dir /a-d') do set /a FileNum+=1
  18. echo.&echo     本程序将创建临时文件夹 %root%\tmp ,里面存放的是程序运行期间产
  19. echo   生的各种临时数据。为便于跟踪测试,本程序保留所有的临时文件,这
  20. echo   些文件可在程序运行完毕后全部删除。无论删除与否,都不会影响程序
  21. echo   下一次运行的结果。
  22. echo.&echo     正在处理数据。视待处理数据量的大小,这个过程将持续数分钟到
  23. echo   数十分钟不等,请耐心等待...
  24. rem ==========生成各种临时文件=============
  25. :: 提取原始文件中的相关信息,重新组合,写入临时文件,以备最后的统计
  26. rd /q /s %root%\tmp 2>nul
  27. setlocal enabledelayedexpansion
  28. :: 把每个月的相关的临时数据写入以月份命名的临时文件夹下
  29. :: 要做的一些事情:过滤每个文件的头5行(skip=5)、重新组合相关数据(关键处之一)
  30. :: 生成每个月的第一个临时文件
  31. for /f "skip=%FileNum% tokens=1-6 delims=\" %%i in ('dir /a-d /b /s') do (
  32.     title 正在提取 %%i\%%j\%%k\%%l\%%m\%%n 中数据
  33.     set month=%%l
  34.     set month=!month:~7,2!
  35.     md %root%\tmp\!month! 2>nul
  36.     if not exist %root%\tmp\!month!\tmp1.txt (
  37.         echo ;本文件为临时中转文件,在 %%i\%%j\%%k 下!month!月份数据的基础上产生
  38.         echo ;处理结果请看 %root%\tmp\%%i\tmp2.txt
  39.         echo ;以下数据的含义为:交易帐号 纯数字文件夹名 纯数字文件名
  40.         echo ;因为原文件数据格式不尽一致的原因,某些行的数据含义与上述描述不尽相符
  41.         echo ;
  42.     )>%root%\tmp\!month!\tmp1.txt
  43.     for /f "skip=5" %%x in (%%i\%%j\%%k\%%l\%%m\%%n) do (
  44.         echo %%x %%m %%n>>%root%\tmp\!month!\tmp1.txt
  45.     )
  46. )
  47. cd.>result.txt
  48. :: 生成每个月的第二个临时文件
  49. for /f %%i in ('dir /ad /b %root%\tmp') do (
  50.     if not exist %root%\tmp\%%i\tmp2.txt (
  51.         echo ;本文件为临时中转文件,在 %root%\tmp\%%i\tmp1.txt 的基础上产生
  52.         echo ;为后续处理做准备,处理结果请看 %root%\tmp\tmp_%%i.txt
  53.         echo ;以下数据的含义为:交易帐号 纯数字文件夹名 纯数字文件名
  54.         echo ;
  55.     )>%root%\tmp\%%i\tmp2.txt
  56.     findstr /b "[0-9]" %root%\tmp\%%i\tmp1.txt>>%root%\tmp\%%i\tmp2.txt
  57.     for /f "delims==" %%j in ('set num_ 2^>nul') do set %%j=
  58.     for /f "tokens=1-3" %%j in (%root%\tmp\%%i\tmp2.txt) do (
  59.         title 正在统计%%i月份数据
  60.         set /a num_%%k+=1&set /a num_%%k_%%l+=1
  61.     )
  62.     (
  63.         echo ;本文件为临时中转文件,在所有子目录下的tmp2.txt基础上产生
  64.         echo ;处理结果请看 %cd%\result.txt
  65.         echo ;以下数据的含义为:纯数字文件夹名 月份 总数 或者 纯数字文件夹名 月份 纯数字文件名 小计
  66.         echo ;
  67.     )>%root%\tmp\tmp_%%i.txt
  68.     for /f "tokens=2,3,4 delims=_=" %%j in ('set num_') do (
  69.         if "%%l"=="" (
  70.             >>%root%\tmp\tmp_%%i.txt echo %%j %%i      %%k
  71.         ) else (
  72.             >>%root%\tmp\tmp_%%i.txt echo %%j %%i %%k %%l
  73.         )
  74.     )
  75.     for /f "tokens=1-4" %%j in ('sort %root%\tmp\tmp_%%i.txt') do (
  76.         if "%%m"=="" (
  77.             (echo.&echo %%j %%k月份新开户数 %%l,其中:)>>result.txt
  78.         ) else (
  79.             >>result.txt echo     %%l 为 %%m
  80.         )
  81.     )
  82. )
  83. (echo.&echo 程序开始运行时间 %begin%,结束运行时间 %time%)>>result.txt
  84. start result.txt
复制代码
  应楼主的要求,为保密起见,不提供原始数据,请原谅。
作者: namejm    时间: 2008-2-1 21:32

  楼主的要求经常变换,一些代码已经不再适合楼主,暂时不作关注。
作者: dreamboc    时间: 2008-2-3 19:44

非常抱歉啊
要求更改了几次
谢谢论坛朋友。活活




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