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

[文件操作] [已解决]批处理怎样按指定大小分割txt文档?

家有txt小说若干,常有学生下载到mp4或手机内存卡,一般没有问题。但时间一长,发现有个别的mp4和手机无法打开较长的文档。解决的办法就是将长文件切成若干个小文件。于是乎,不断的复制一小段内容,新建一个txt文档,打开这个新建的文档,粘贴,关闭,保存:然后周而复始地重复这个过程。也许一个小时或几个小时还没完成一部小说的下载,极其麻烦。希望能有一个小程序能一点就解决。大致想法是这样的:输入小说的地址和文件名,回车后,立刻产生一个同名文件夹,文件夹内是按100k切分的若干txt,名字为文件夹名加1、2、3....等,最后的那个文件当然会小于100k。(特别要求,每个切分的txt文档必须以中文句号、英文句号或中英文问号结束,这样可以保证文档的大小不超过100k,并且相对完整的结束。)
谢谢各位回答者和看客。

我想过按自然段落来切割,但考虑到不少txt小说根本就不分段,所以还是按标点切割
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

按照楼上这种切割方式是否合理呢?

按照人家文章本自然段落格式来切割是否更人性化?

TOP

来个vbs吧

对于编码是ANSI的文本,一个英文字符占一个字节,一个汉字占两个字节,所以100K就是51200个汉字。最后得到的小文本一般小于100K,可自行调整
  1. if WScript.Arguments.length=0 then msgbox "请把文本拖到脚本上" : wscript.quit
  2. Set fso = CreateObject("Scripting.FileSystemObject")
  3. set f = fso.GetFile(WScript.Arguments(0))
  4. set ts = f.OpenAsTextStream
  5. strText = ts.ReadAll
  6. fp = f.ParentFolder
  7. fn = left(f.Name,InStrRev(f.Name,".")-1)
  8. set f = nothing
  9. if not fso.FolderExists(fp&"\"&fn) then fso.CreateFolder fp&"\"&fn
  10. strtext=Replace(strtext, "。", "。///")
  11. strtext=Replace(strtext, "?", "?///")
  12. strtext=Replace(strtext, "!", "!///")
  13. strtext=Replace(strtext, ".", ".///")
  14. strtext=Replace(strtext, "!", "!///")
  15. strtext=Replace(strtext, "?", "?///")
  16. a=split(strtext,"///")
  17. i=0:j=0:k=1
  18. do while i<=UBound(a)
  19.     j=j+len(a(i))
  20.     if j<51200 then
  21.         fso.OpenTextFile(fp&"\"&fn&"\"&fn&"-"&k&".txt",8,true).Write a(i)
  22.     else
  23.         j=0
  24.         k=k+1
  25.         fso.OpenTextFile(fp&"\"&fn&"\"&fn&"-"&k&".txt",8,true).Write a(i)
  26.     end if
  27.     i=i+1
  28. loop
复制代码

[ 本帖最后由 zqz0012005 于 2008-10-10 14:47 编辑 ]
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

Re 37楼
文件大小为100 k 应该是纯属巧合,(不过似乎也太巧了点)
第二个文件过大的原因是因为第一个文件的最后一行太长的缘故。

代码运行原理如下:
set /a n=101600   
102400 为100k 这里特意取了一个偏小的植,目的是为了防止文件大于100 k (若文件还是太大,可将此
值再改小)
findstr /o 可以在文件的每行显示前面文件的字节数(既:大小)当此值大于101600 时,则开始准备分

割文件。
先判断此时的最后一行是否含有 句号,若没有则再判断上一行,直到发现句号为止。
再将此行第一个句号的前面部分作为这个文件的结尾,后面的部分作为下一个文件的开头。
若是此行太长的话,那么写入下一行开头的内容就会越多,所以就有可能导致下一个文件过大。
解决办法是减小   set /a n=101600 值,但这样会导致其他文件的会偏小。

不过 37 楼 Batcher 巡查 说的也没错,我在36楼以明确说明 (可自行修改 set /a n=101600 数值的大

小)你若仔细看了话,
应该自己先试一试,不要过于依赖别人现成的代码。

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

TOP

回复 37楼 的帖子

希望此帖能开拓楼主自己动手的习惯
36楼写的很清楚“可自行修改 set /a n=101600 数值的大小”
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

随风,你好!昨晚没有睡吧,06点06分还在修改帖子,辛苦了。
测试了你的代码,本机35秒左右,还可以,其他的要求也能达到,但我发现切分的第二个txt文档是101k,其他都是100k,最后的那一个除外。第二个txt文档是101k,这是怎么回事呢?纯代码讨论,其实也不影响我的使用。
不知大家烦不烦我,这个帖子费了很多朋友的时间和精力,还可能有其他的修正代码的出现,
希望此贴能开拓各位解决问题的思路和注意细节的习惯。
不知何时可以结贴,希望还晚一点,期待更多的优秀帖子出现。

[ 本帖最后由 yylogo 于 2008-10-10 11:33 编辑 ]

TOP

不用第三放软件还真是有点吃力。
初步测试成功
   以中文句号结尾。
   文件大小基本不大于100 k (可自行修改 set /a n=101600 数值的大小)
缺点:
   1、效率低 样本文件 2.22m  耗时: 0 小时 1 分钟 3 秒 28 毫秒
   2、文件内容不能含有特殊符号
        如:英文的 " %^&<>()!&  大概就这几个,不一定全是,但肯定有。。。
  为提高效率创建了一个临时文件 tmp.txt (完成后会自动删除)
:
  1. @echo off
  2. set /a n=101600,kb=n
  3. set "临时文件=tmp.txt"
  4. set /p file=请把要处理的文件拖到此处:
  5. set "file=%file:"=%"
  6. cls&echo  正在分割 %file% 文件请稍候。。。
  7. for /f "delims=" %%a in ("%file%") do set wjm=%%~na
  8. findstr /no ".*" "%file%">"%临时文件%"
  9. for /f "tokens=2 delims=:" %%a in ('find /c /v "" "%临时文件%"') do set /a z=%%a
  10. if not exist "%wjm%\" md "%wjm%"
  11. :list
  12. set /a x+=1
  13. if defined t >>"%wjm%\%wjm%_%x%.txt" echo %t%
  14. set "t="
  15. if not defined h (set skip=) else (set skip=skip=%h%)
  16. setlocal enabledelayedexpansion
  17. for /f "%skip% tokens=1,2* delims=:" %%a in (%临时文件%) do (
  18.    if %%b geq !kb! set /a kb+=n&set flag=a&goto loop
  19.    set /a g+=1
  20.    set !g!=%%c&set /a h=%%a,u=%%a
  21. )
  22. :loop
  23. if not defined flag (
  24.    if defined t >>"%wjm%\%wjm%_%x%.txt" echo %t%
  25.    for /l %%a in (1 1 !g!) do >>"%wjm%\%wjm%_%x%.txt" echo.!%%a!
  26.    goto end
  27. )
  28. set "var=!%g%!"
  29. if not defined var set /a g-=1,h-=1&goto loop
  30. for /f "tokens=1* delims=。" %%a in ("!var!") do (
  31.    if "!var!"=="%%a" set /a g-=1,h-=1&goto loop
  32.    if not "%%b"=="" set "t=%%b"
  33.    set w=%%a。
  34. )
  35. for /l %%a in (1 1 !g!) do >>"%wjm%\%wjm%_%x%.txt" echo.!%%a!
  36. >>"%wjm%\%wjm%_%x%.txt" echo !w!
  37. endlocal&set h=%h%&set t=%t%&set kb=%kb%&set "u=%u%"
  38. if %u% neq %z% goto list
  39. :end
  40. del/q "%临时文件%" 2>nul
  41. start "" "%wjm%"
复制代码

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

TOP

回复 32楼 的帖子

日志文件,没办法。我们那台服务器有4个CPU,4G的内存,都无法用记事本打开(可以用第三方工具打开),你的电脑就更不行啦^_^

为啥那个C代码能准确保证每一篇40k呢?因为它在写文件的时候,是逐字写入的。为啥 terse 兄给你的BAT代码会小的误差呢,因为它在写文件的时候,是逐行写入的。

在这个问题上,C比BAT强吗?如果要考虑标点符号,就必须逐字判断,这时BAT要考虑特殊字符的问题,而C则没有这个顾忌,从这一点上来考虑C确实比BAT强。C是语言,BAT是脚本,其实不应该放在一起比较的。

既然那个C代码是逐字写入文件的,那么,如果你具备C基础,稍加修改即可实现要求。如果你具备BAT基础,再好好看看30楼的回复,就知道怎么实现"不大于100k"了。

还有,你把那个C代码中的39999改成100000,看看结果如何^_^
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

也发现了如此的问题,应该是是split.exe的BUG。对此无能为力~
心绪平和,眼藏静谧。

TOP

回复 31楼 的帖子

测试了你31楼的代码,效果相当的完美,没有一个文件超过100k,所有的文件都是以段落结尾。而且,切分的效率非常高,2.23m的文档,不到2秒钟。
但在我查找文章前后连贯的时候,发现了一个致命的缺陷,我想,这是所有人都始料未及的,那就是从切分的第二个文件开始,每篇文章的第一二段出现了或多或少的乱码。
这个问题是不是第三方软件的bug造成的呢?你们试一试吧。我将一个2.23m的txt小说上传到了论坛2号群空间共享里面,标题是:切分代码试验文档.txt
第三方看样子靠不住,和第三者插足一样,不要太相信了,是不是可以解剖一下第三方软件的源代码呢。

TOP

回复 29楼 的帖子

700m的txt的文件,o my god,我的双核cpu,2g内存,肯定是打不开的,100%肯定,那不成了屎壳螂,加那么大干吗?
话又说回来,真要看你说的这么大的txt,还真必须要使用我们在这探讨的切分问题(不知警察有没有)。所以,18楼的效率还真是个问题。(我使用就那么大-不超过10m,不存在问题)
我在12楼贴的c代码,切分2.22m的txt,不到1秒钟。不过,就是一刀切,每一篇40k,不大不小,不管结尾有没有标点符号。是不是说,在这个问题上,c比bat强呢。如果让那段c代码寻找结尾的标点符号,会不会也出现效率的问题呢?
不好意思,我只会问问题,不会写。

TOP

去掉了wfr.exe 只用SPLIT.EXE。应该可以了。
  1. @echo off
  2. :loop
  3. setlocal enabledelayedexpansion
  4. set/p file=请把要处理的文件拖到此处:
  5. for /f "delims=" %%a in ("%file:"=%") do (
  6.      md "%%~na"
  7.      split -b 99k "%file:"=%" "%%~na\%%~na_"
  8.      ren "%%~na\*" "*.txt"
  9.      set "name=%%~na"
  10. )
  11. for /f "delims=" %%a in ('dir /b /s /on "%name%\*.txt"') do set/a n+=1&set "_!n!=%%a"
  12. set/a n-=1
  13. for /l %%i in (1 1 %n%) do (
  14.      set/a x=%%i+1
  15.      findstr /v $ "!_%%i!">tmp&findstr $ "!_%%i!">tmp1
  16.      move /y tmp1 "!_%%i!"
  17.      (type tmp&echo.&call type "%%_!x!%%")>tmp2
  18.      call,move /y tmp2 "%%_!x!%%"
  19. )
  20. del tmp
  21. endlocal
  22. pause
复制代码
心绪平和,眼藏静谧。

TOP

批处理的效率肯定不理想 代码也没你想那么好  只是你的文本每行字符都在范围内,也因每行的结束都是标点,那样的话又可避免切分好的文本最后缺少标点问题
另把102400改小一下试看如何 你可以改为102300 102200 102100  直到满意

TOP

回复 28楼 的帖子

公司一台服务器用来存放日志的txt文档已经700MB了,还在每天增加......
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

返回列表