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

【出题】批处理给文本文件ab cd.txt每行前加上日期

出题:给ab cd.txt每行前加上日期
已知:
   ab cd.txt 文件名含空格。(不能改文件名)
   ab cd.txt 行数不确定 (大约5万行左右),无空行,且不含特殊符号。
.
要求:
   1、给ab cd.txt每行前面加上日期,将结果写入 c.txt
   2、最后一行为当前日期,倒数第二行为昨天的日期,倒数第三行为前天的日期,依此类
推。。。。
   3、并在跨月份时插入空行。
   如:09月30日 和 10月01日 之间需插入一空行。
  1.    2008年09月28日 为什么要学习批处理
  2.    2008年09月29日 1.源自于批处理的简单
  3.    2008年09月30日 我想没有多少人愿意花上一个月甚至更多的时间
  4.    2008年10月01日 去绞尽脑汁的专门学习一个编程语言来写一个删除系统垃圾的程序,
  5.    2008年10月02日 因为对于一个不是专门学习计算机或者将来从事这方面工作的人来说,
  6.    2008年10月03日 这样的投入与产出实在是不值得的,
  7.    2008年10月04日 而用我们的批处理只要几分钟就可以解决这个问题,
复制代码
代码要求:
  1、不产生临时文件
  2、用纯p解决。
  3、必须考虑跨年度、跨月份、及闰年的情况。
  4、代码运行耗时不能超过一分钟。
.
加分条件:
   1、效率高   +5
   2、代码简洁 +3
   3、满分    +10
.

假设ab cd.txt内容为:
  1. 为什么要学习批处理
  2. 1.源自于批处理的简单
  3. 我想没有多少人愿意花上一个月甚至更多的时间
  4. 去绞尽脑汁的专门学习一个编程语言来写一个删除系统垃圾的程序,
  5. 因为对于一个不是专门学习计算机或者将来从事这方面工作的人来说,
  6. 这样的投入与产出实在是不值得的,
  7. 而用我们的批处理只要几分钟就可以解决这个问题,
  8. 这样的方便性让任何对计算机望而生畏的人来说是多么的有吸引力。
  9. 2.通过批处理的编写,会逐渐的熟悉windows操作系统的一些细节问题,
  10. 仅此一点就能让你在众多菜鸟中脱颖而出。
  11. 3.通过diy自己的“程序”让自己有种成就感,
  12. 这种感觉绝对不是使用别人的工具所能言语的,
  13. 自己能写出来东西就是对自己最好的证明。
  14. 4.强大性,baidu,google里不可能搜索到能帮你解决掉所有问题的程序,
  15. 如果你不会写那些.exe程序,
  16. 那么你要完成你的目标可能就要花些银子让一些软件工作室帮你写咯。
  17. 其实决大部分系统的问题,.bat都可以轻松的帮你解决掉了。
  18. 说了这么多,到底为什么要学习批处理就是很简单的一句话:
  19. 程序是写出来满足绝大部分人的,而批处理是满足我们自己的。
  20. 每个拥有计算机和懂计算机的人都应该学习批处理。
  21. 因为世界上任何一个人都能通过简单的学习掌握批处理这门“编程语言”
复制代码
假设当前日期为: 2008年10月18日
要求 c.txt 结果如下:
  1. 2008年09月28日 为什么要学习批处理
  2. 2008年09月29日 1.源自于批处理的简单
  3. 2008年09月30日 我想没有多少人愿意花上一个月甚至更多的时间
  4. 2008年10月01日 去绞尽脑汁的专门学习一个编程语言来写一个删除系统垃圾的程序,
  5. 2008年10月02日 因为对于一个不是专门学习计算机或者将来从事这方面工作的人来说,
  6. 2008年10月03日 这样的投入与产出实在是不值得的,
  7. 2008年10月04日 而用我们的批处理只要几分钟就可以解决这个问题,
  8. 2008年10月05日 这样的方便性让任何对计算机望而生畏的人来说是多么的有吸引力。
  9. 2008年10月06日 2.通过批处理的编写,会逐渐的熟悉windows操作系统的一些细节问题,
  10. 2008年10月07日 仅此一点就能让你在众多菜鸟中脱颖而出。
  11. 2008年10月08日 3.通过diy自己的“程序”让自己有种成就感,
  12. 2008年10月09日 这种感觉绝对不是使用别人的工具所能言语的,
  13. 2008年10月10日 自己能写出来东西就是对自己最好的证明。
  14. 2008年10月11日 4.强大性,baidu,google里不可能搜索到能帮你解决掉所有问题的程序,
  15. 2008年10月12日 如果你不会写那些.exe程序,
  16. 2008年10月13日 那么你要完成你的目标可能就要花些银子让一些软件工作室帮你写咯。
  17. 2008年10月14日 其实决大部分系统的问题,.bat都可以轻松的帮你解决掉了。
  18. 2008年10月15日 说了这么多,到底为什么要学习批处理就是很简单的一句话:
  19. 2008年10月16日 程序是写出来满足绝大部分人的,而批处理是满足我们自己的。
  20. 2008年10月17日 每个拥有计算机和懂计算机的人都应该学习批处理。
  21. 2008年10月18日 因为世界上任何一个人都能通过简单的学习掌握批处理这门“编程语言”
复制代码

[ 本帖最后由 随风 于 2008-10-18 22:33 编辑 ]
技术问题请到论坛发帖求助!

可以做到 但效率不理想

TOP

这个应该难不住 terse 兄,效率问题只要写代码时多费费脑筋就ok了   ^_^

5 万行 一分钟左右 。。。。
这个效率应该可以接受。

这是帮一朋友写代码时想到的,若不讲究效率则此题就不难了。
对批处理的语法要求更高,对入门不久的新手应该是很好的练手题目。。。
技术问题请到论坛发帖求助!

TOP

这题主要麻烦在日期处理,其他没什么。关于日期处理cn-dos有很多现成的代码。我也不想再去找了。

以前在cn-dos收集的代码,修理硬盘备份在同学的电脑上,后来被他删了。扁死他也找不回来了。也没有时间和那份心情再去重新收集
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

纯P是不是不让调外部命令?
可以用reg.exe么?

TOP

用 reg ?
没有任何思路。。
只要是系统自带的命令都可以。
期待结果。。。
技术问题请到论坛发帖求助!

TOP

1867年计算到2008 整4分
重新整理下再看

TOP

批处理对日期的处理实在麻烦,来个vbs先
  1. Set fso = CreateObject("Scripting.FileSystemObject")
  2. set f = fso.OpenTextFile("ab cd.txt")
  3. f.ReadAll : lines = f.Line : f.Close
  4. set f = fso.OpenTextFile("ab cd.txt")
  5. Do While f.AtEndOfStream <> True
  6.     s =s & GetDate(f.Line) & " " & f.ReadLIne & vbCrLf
  7. Loop
  8. fso.OpenTextFile("c.txt",2,True).Write s
  9. Function GetDate(nDiff)
  10.     nDate = DateAdd("d", nDiff-lines, date)
  11.     if month(nDate) <> month(nDate-1) then strMonChange = vbCrLf
  12. GetDate = strMonChange & _
  13.         year(nDate) & "年" & _
  14.         right("0" & month(ndate), 2) & "月" & _
  15.         right("0" & day(ndate), 2) & "日"
  16. End Function
复制代码
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

哈哈,小楼兄摆明的是在出难题啊,经测算日期计算只能用32秒左右的时间,确实是个挑战。。。

[ 本帖最后由 batman 于 2008-10-19 09:21 编辑 ]
***共同提高***

TOP

抛砖了!!!

仅做到日期从当前开始输出:
测试文本生成代码:
  1. @echo off&for /l %%i in (1,1,50000) do echo %%i>>"ab cd.txt"
复制代码
解题代码:
  1. @echo off&setlocal enabledelayedexpansion
  2. set "t=%time%"&echo.>c.txt
  3. set /a year=%date:~,4%,month=1%date:~5,2%%%100,day=1%date:~8,2%%%100,yun=29
  4. for /f "usebackq delims=" %%i in ("ab cd.txt") do (
  5.     echo !year!-!month!-!day! %%i>>c.txt
  6.     set /a day-=1
  7.     if !day! equ 0 (
  8.        echo.>>c.txt
  9.        set /a month-=1
  10.        if !month! equ 0 (
  11.           set /a year-=1,month=12,day=31&call :lp1
  12.           ) else (
  13.           call :lp2
  14.        )
  15.     )
  16. )
  17. echo 程序开始时间为:%t%
  18. echo 程序结束时间为:%time%
  19. pause>nul&goto :eof
  20. :lp1
  21. set /a a=year%%4,b=year%%100,c=year%%400,yun=28
  22. if %b% equ 0 (
  23.    if %c% equ 0 set "yun=29"
  24.    ) else (
  25.    if %a% equ 0 set "yun=29"
  26. )
  27. goto :eof     
  28. :lp2
  29. for /f "tokens=%month%" %%a in ("1#31 2#%yun% 3#31 4#30 5#31 6#30 7#31 8#31 9#30 10#31 11#30 12#31") do (
  30.     for /f "tokens=2 delims=#" %%i in ("%%a") do set "day=%%i"
  31. )
复制代码
经pusofalse版主提醒修改部分代码后再测试(本人机子慢了),测试时间如下:
***共同提高***

TOP

日期反过来输出不是做不到,只是一时只想到设置变量的办法,但设置50000个变量就根本谈不上效率了。。。不知随风兄有何妙法?
***共同提高***

TOP

我是这样处理的  确定文本行数  然后就是总行数之前的日期   开始累加1  直到文本结束
似乎效率不理想
代码简化一下  但效率没上去
本想以年为递减  结果有差错  改回
  1. @echo off
  2. echo 开始时间 %time%
  3. for /f "tokens=1-3 delims=-/\:. " %%i in ("%date%") do set /a p1=%%i,p2=100%%j%%100,p3=100%%k%%100
  4. set/a PN2="!(p1%%4) & !(!(p1%%100)) | !(p1%%400)",PN2+=28
  5. for /f "tokens=%p2%" %%i in ("31 !pN2! 31 30 31 30 31 31 30 31 30 31") do set pt=%%i
  6. for /f "delims=" %%i in ('type "abcd.txt"^|find /v /c ""') do set /a tt=%%i
  7.     cd.>b.txt
  8.     setlocal enabledelayedexpansion
  9.     for /f "usebackq delims=" %%i in ("abcd.txt") do (
  10.     if not defined b set b=p&call :lp
  11.     if !p3! gtr !pt! set/a p3-=pt,p2+=1&call:next
  12.     if !p2! lss 10 (set m2=0!p2!)else set m2=!p2!
  13.     if !p3! lss 10 (set d3=0!p3!)else set d3=!p3!
  14.     >>b.txt echo !p1!年!m2!月!d3!日 %%i
  15.     if !p3! equ !pt! >>b.txt echo.
  16.     set/a p3+=1
  17. )
  18.     echo 结束时间 %time%
  19.     pause&exit /b
  20. :next
  21.     if !p2! gtr 12 set/a PN2="^!(p1%%4) & ^!(^!(p1%%100)) | ^!(p1%%400)",PN2+=28,p1+=1,p2=p2%%12
  22.     for /f "tokens=%p2%" %%i in ("31 !pN2! 31 30 31 30 31 31 30 31 30 31") do set pt=%%i
  23.     goto :eof
  24. :lp
  25.     set/a p2-=1
  26.     if %p2% equ 0 set/a PN2="^!(p1%%4) & ^!(^!(p1%%100)) | ^!(p1%%400)",PN2=28+PN2,p1-=1,p2=12
  27.     for /f "tokens=%p2%" %%i in ("31 %pN2% 31 30 31 30 31 31 30 31 30 31") do set/a p3+=%%i&set pt=%%i
  28.     if %p3% leq %tt% goto lp
  29.     set/a p3-=tt
  30.     goto :eof
复制代码


再修正一下  以年递减 不满一年 以月递减
修正一个 在行数小的情况出现的BUG
  1. @echo off
  2. echo 开始时间 %time%
  3. for /f "tokens=1-3 delims=-/\:. " %%i in ("%date%") do set /a p1=%%i,p2=100%%j%%100,p3=100%%k%%100
  4.     set/a pn="!(p1%%4) & !(!(p1%%100)) | !(p1%%400)",pn+=28,pn2=pn+31
  5.     for /f "tokens=%p2%" %%i in ("31 %pn% 31 30 31 30 31 31 30 31 30 31") do set pt=%%i
  6.     for /f "tokens=%p2%" %%i in ("0 31 %pn2% 90 120 151 181 212 243 273 304 334") do set/a p3+=%%i
  7.     for /f "delims=" %%i in ('type "ab cd.txt"^|find /v /c ""') do set /a tt=%%i-1
  8.     if %tt% gtr %p3% (set/a tt-=p3,p1-=1,p2=12,p3=31)else goto lp2
  9. :lp
  10.     set/a pn="!(p1%%4) & !(!(p1%%100)) | !(p1%%400)",pn+=365
  11.     if %tt% gtr %pn% set/a tt-=pn,p1-=1&goto lp
  12.     set/a pn="!(p1%%4) & !(!(p1%%100)) | !(p1%%400)",pn+=28
  13. :lp1
  14.     if %p3% gtr %tt% goto lp2
  15.     set/a p2-=1
  16.     for /f "tokens=%p2%" %%i in ("31 %pn% 31 30 31 30 31 31 30 31 30 31") do set/a p3+=%%i&set pt=%%i
  17.     if %p3% leq %tt% goto lp1
  18. :lp2
  19.     set/a p3-=tt
  20.     cd.>b.txt
  21.     setlocal enabledelayedexpansion
  22.     for /f "usebackq delims=" %%i in ("ab cd.txt") do (
  23.     if !p3! gtr !pt! set/a p3-=pt,p2+=1&call:next
  24.     if !p2! lss 10 (set m2=0!p2!)else set m2=!p2!
  25.     if !p3! lss 10 (set d3=0!p3!)else set d3=!p3!
  26.     >>b.txt echo !p1!年!m2!月!d3!日 %%i
  27.     if !p3! equ !pt! >>b.txt echo.
  28.     set/a p3+=1
  29. )
  30.     echo 结束时间 %time%
  31.     pause&exit /b
  32. :next
  33.     if !p2! gtr 12 set/a pn="^!(p1%%4) & ^!(^!(p1%%100)) | ^!(p1%%400)",pn+=28,p1+=1,p2=p2%%12
  34.     for /f "tokens=%p2%" %%i in ("31 !pn! 31 30 31 30 31 31 30 31 30 31") do set pt=%%i
  35.     goto :eof
复制代码

[ 本帖最后由 terse 于 2008-10-20 13:48 编辑 ]

TOP

看了这段代码,人都要晕了。。。。我也想过用这种方法,但这样效率肯定是上不去的,因
为这样要进行100000次日期计算,其中还要进行很多次的判断,但另一种平常好用的设置
变量法实践中效率更低(变量数量太大了),所以一直未能达到小楼兄的要求。。。
用kip的方法可以将文本未行变成首行,但输出就整个是反过来的,即当前日期和未行成了第
一行,再用一次skip就可以按要求输出了,但这样既显得罗索,效率也达不到一分左右完成
这一要求,同时可能还要生成一次临时文件。。。
期待小楼兄的答案。。。
***共同提高***

TOP

  1. @echo %time%
  2. @echo off & setlocal enabledelayedexpansion
  3. set sOldFile="ab cd.txt"
  4. set sNewFile="c.txt"
  5. for %%a in (31 28 31 30 31 30 31 31 30 31 30 31) do set /a i += 1 && set iM!i!=%%a
  6. for /f "tokens=1-3 delims=-" %%a in ("%date%") do set iThisYear=%%a & set iThisMonth=%%b & set iThisDay=%%c
  7. set /a iLeapYearCount = (iThisYear - 1) / 4 - (iThisYear - 1) / 100 + (iThisYear - 1) / 400
  8. call :GetFebDayCount %iThisYear% iM2
  9. for /l %%a in (1, 1, %iThisMonth%) do if %%a lss %iThisMonth% set /a iThisMonthToDayCount += iM%%a
  10. set /a iAllDayCount = 365 * (iThisYear - 1) + iLeapYearCount + iThisMonthToDayCount + iThisDay
  11. for /f "usebackq delims=" %%a in (%sOldFile%) do set /a iDayDiff += 1
  12. set /a iFirstDayCount = iAllDayCount - (iDayDiff - 1)
  13. set /a iTempYear = iFirstDayCount / 365 - 1
  14. :GetDate
  15. set /a iTempLeapCount = iTempYear / 4 - iTempYear / 100 + iTempYear / 400
  16. set /a iTempDayCount = iFirstDayCount - 365 * iTempYear - iTempLeapCount
  17. if %iTempDayCount% lss 0 set /a iTempYear -= 1 && goto :GetDate
  18. if %iTempDayCount% equ 0 set /a iYear = iTempYear, iMonth = 12, iDay = 31 && goto :WriteText
  19. set /a iYear = iTempYear + 1
  20. call :GetFebDayCount %iYear% iM2
  21. for /l %%a in (1, 1, 12) do (
  22. set /a iTempDayCount -= iM%%a
  23. if !iTempDayCount! leq 0 set /a iMonth = %%a, iDay = iM%%a + iTempDayCount, iTempDay = iM%%a && goto :WriteText
  24. )
  25. :WriteText
  26. cd.>%sNewFile%
  27. for /f "usebackq delims=" %%a in (%sOldFile%) do (
  28. if !iMonth! lss 10 (set sMonth=0!iMonth!) else (set sMonth=!iMonth!)
  29. if !iDay! lss 10 (set sDay=0!iDay!) else (set sDay=!iDay!)
  30. >>%sNewFile% echo !iYear!年!sMonth!月!sDay!日 %%a
  31. if !iDay! lss !iTempDay! (
  32. set /a iDay += 1
  33. ) else (
  34. >>%sNewFile% echo.
  35. if !iMonth! lss 12 (
  36. set /a iMonth += 1, iDay = 1
  37. ) else (
  38. set /a iYear += 1, iMonth = 1, iDay = 1
  39. call :GetFebDayCount !iYear! iM2
  40. )
  41. set /a iTempDay = iM!iMonth!
  42. )
  43. )
  44. echo %time%
  45. pause
  46. exit /b
  47. :GetFebDayCount
  48. for %%a in (4 100 400) do set /a r%%a=%1%%%%a
  49. set %2=28
  50. if %r400%==0 (set %2=29) else (if %r4%==0 if not %r100%==0 set %2=29)
复制代码

[ 本帖最后由 rat 于 2008-10-20 16:55 编辑 ]
2

评分人数

    • pusofalse: 果真高人。PB + 15 技术 + 1
    • batman: 高人,建议加入我们的版主行列PB + 15 技术 + 1

TOP

原帖由 batman 于 2008-10-19 19:40 发表
看了这段代码,人都要晕了。。。。我也想过用这种方法,但这样效率肯定是上不去的,因
为这样要进行100000次日期计算,其中还要进行很多次的判断,但另一种平常好用的设置
变量法实践中效率更低(变量数量太大了) ...

其实没有进行100000次日期计算  假设50000行 就是50000次运算啊  其中判断少不了的

TOP

返回列表