Board logo

标题: [文本处理] [已解决]批处理怎样随机打乱文本段落? [打印本页]

作者: fanfande    时间: 2011-5-27 19:05     标题: [已解决]批处理怎样随机打乱文本段落?

本帖最后由 fanfande 于 2011-5-31 22:39 编辑

文件夹A里面的N个txt文件,想通过批处理功能实现每个文本都段落打乱功能!
打乱是随机的,每次运行的结果都不一样!
结果生成在另外一个新的文件夹B里面!

哪位高手帮帮忙
祝大家周末愉快!


段落的标志是

行与行之间有空行就是段落啊!具体应该这样定义段落:
行与行之间有有一行或一行以上的空行就算是段落!
比如我这个提问的问题要是算的上一个txt的话,那就是4段!
谢谢大家!周末回老家了一下!
作者: batman    时间: 2011-5-27 19:09

楼主所说的段落概念是什么,一段最多有多少个字符?
作者: fanfande    时间: 2011-5-27 20:51

2# batman


你好版主
就是普通的段落,没什么特殊的要求

比如一个文档里面有5段,那么让他们随机排列就是p55排列组合里面随机一个!
作者: CrLf    时间: 2011-5-27 21:03

段落短而且不含“!”号可以:
  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "delims=" %%a in (a.txt) do set \!random!=%%a
  3. for /f "tokens=1* delims==" %%a in ('set\') do echo %%b
  4. pause
复制代码

作者: CrLf    时间: 2011-5-27 21:08

段落长,或者含有特殊字符!也都有办法处理,不过耗时大增。
而段落中若既含!,又含%,那就比较麻烦了...
作者: batman    时间: 2011-5-27 21:10

那如何判断为一段,有什么标志?
作者: 随风    时间: 2011-5-27 21:15

我理解为,行开头空格的就是一段的开始。
作者: CrLf    时间: 2011-5-27 21:25

希望楼主在顶楼更新一下,贴出前后对比的样本,以作范例
作者: cjiabing    时间: 2011-5-28 02:12

本帖最后由 cjiabing 于 2011-5-28 02:15 编辑
  1. 摘自《BatMPlayer 2011 Beta V3.28.5.15》,有修改。
  2. ::随机排序。使用随机变量%random%和%time%、findstr和sort命令组合,可对文本内容进行随机排序。先使用findstr获得行号,在行号中加入随机数%random%,变成新序号,然后使用sort重新排序。
  3. ::%random%在for中只发生了一次变化,即使用%time%也一样。使用call外部%random%的方式,虽然速度变慢了,但可以采集到不同的变量。%time:~-2,2%可以取得00至99的“伪随机数”,但存在00、01、09这样以0开头的数字。%random:~-2,2%可以取得很好的随机数,但需要确定随机数的位数(长度),比较麻烦。%random:~-2,2%要比%random:~0,2%随机变化大一些,后者在十分短的时间内取值可能存在重复不变,原因可能与%time%有关。
  4. ::“sort /+n”表示按照行的第N个字符的正向顺序排序,也可以使用“sort /-n”实现颠倒顺序,可能对短行效果不明显。可以进行【set /a a=00+02】的计算,但【set /a a=07+07】的计算是失败的,【set /a a=09+02】也可能失败。
  5. @echo off&setlocal enabledelayedexpansion
  6. set bjt=test.txt
  7. set fn=
  8. cd.>"%temp%\_pl.tmp"&cd.>"%temp%\_pls.tmp"
  9. for /f "tokens=1,* delims=:" %%a in ('findstr /n .* !bjt!') do (
  10.     if not "%%a"=="" set lx=%%a
  11.     call :dt
  12.     echo;!fn!:%%b>>"%temp%\_pl.tmp"
  13. )>nul 2>nul
  14. for /f "tokens=1,* delims=:" %%a in ('sort "%temp%\_pl.tmp"') do echo;%%b>>"%temp%\_pls.tmp"
  15. pause&exit
  16. :dt
  17. set /a fn=!lx!+%random:~-2,2%
  18. goto :eof
复制代码

由于在for中使用了call,速度较差,暂时没想到更好的办法,权宜之计。
作者: 随风    时间: 2011-5-29 23:08

用临时文件,一个段落一个文件,再随机合并这些文件。
作者: batman    时间: 2011-5-29 23:30

本帖最后由 batman 于 2011-5-30 10:50 编辑

vbs的:
  1. Dim opath, npath, fso, vbnum, vbstr, vbout
  2. opath = "这里换成文本所在目录的路径"
  3. Set fso = CreateObject("scripting.filesystemobject")
  4. npath = fso.GetParentFolderName(opath) & "\newfolder"
  5. If fso.FolderExists(npath) Then fso.DeleteFolder(npath)
  6. fso.CreateFolder(npath)
  7. For Each file In fso.GetFolder(opath).Files
  8.   If LCase(fso.GetExtensionName(file)) = "txt" Then vbstr = fso.OpenTextFile(file, 1).ReadAll()
  9.   For i = 0 To UBound(Split(vbstr, vbCrLf & vbCrLf))
  10.     vbnum = vbnum & " " & i & " "
  11.   Next
  12.   sort UBound(Split(vbstr, vbCrLf & vbCrLf)), vbnum
  13.   For Each num In Split(vbnum, " ")
  14.     If num <> "" Then vbout = vbout & Split(vbstr, vbCrLf & vbCrLf)(num) & vbCrLf & vbCrLf
  15.   Next
  16.   fso.OpenTextFile(npath & "\" & file.Name, 2, 1).Write vbout
  17. Next
  18. Set fso = Nothing
  19. MsgBox "ok"
  20. Function sort(num, vbnum)
  21. Dim a, b
  22. Randomize
  23. For a = 0 To num
  24.    b = Int(Rnd * num)
  25.    vbnum = Replace(vbnum, " " & a & " ", "#")
  26.    vbnum = Replace(vbnum, " " & b & " ", " " & a & " ")
  27.    vbnum = Replace(vbnum, "#", " " & b & " ")
  28. Next
  29. End Function  
复制代码
ps:开始看错题意,还写了遍历函数并改写了原文本。。。
作者: 523066680    时间: 2011-5-30 09:59

本帖最后由 523066680 于 2011-5-30 10:10 编辑

也用VBS
  1. set fs=createobject("scripting.filesystemobject")
  2. for each name in fs.getfolder("a").files
  3. if (lcase(right(name,3)) = "txt") then
  4. call deal(name)
  5. end if
  6. next
  7. Function deal(fname)
  8. all=fs.opentextfile(fname).readall
  9. set rs=fs.createtextfile(fname & ".x")
  10. '剔除重复的空行,方法类似某个批处理帖子,将字符串中的任意个连续空格变成1个空格
  11.         '就像 ABABAB,ABAB 剔除BA,始终会得到AB,VBS知识不全,不知道有没有绕弯路。
  12. special=VBCRLF&VBCRLF
  13. all=replace(all , special, special & "#VB#")
  14. all=replace(all , "#VB#" & special,"")
  15. all=replace(all , "#VB#","")
  16. list=split(all,special)
  17. '乱序输出
  18. randomize()
  19. newstr=""
  20. for i = ubound(list) to 0 step -1
  21. randx=int(rnd()*(i+1))
  22. newstr=newstr & list(randx) & vbcrlf & vbcrlf
  23. list(randx)=list(i)
  24. next
  25. rs.write newstr
  26. msgbox newstr
  27. End Function
复制代码
环境条件: 这个vbs和目录a放在一起。
会只处理里面的txt文本。
处理的时候会把结果写入  "原文件名.x" 里面, 依然放在目录a 。
拿楼主的帖子内容测试了
行与行之间有空行就是段落啊!具体应该这样定义段落:
行与行之间有有一行或一行以上的空行就算是段落!
比如我这个提问的问题要是算的上一个txt的话,那就是4段!
谢谢大家!周末回老家了一下!

文件夹A里面的N个txt文件,想通过批处理功能实现每个文本都段落打乱功能!
打乱是随机的,每次运行的结果都不一样!
结果生成在另外一个新的文件夹B里面!

哪位高手帮帮忙
祝大家周末愉快!


段落的标志是


用批处理做吗……  ? 哈,我去工作了,好忙。
作者: powerbat    时间: 2011-5-30 19:10

  1. '用你的文件替换下面的变量,如file = "a.txt"
  2. file = WScript.ScriptFullName
  3. Set fso = CreateObject("Scripting.FileSystemObject")
  4. txt = fso.OpenTextFile(file).ReadAll()
  5. MsgBox(txt)
  6. arr = Split(txt, vbCrLf & vbCrLf)
  7. arrlen = UBound(arr) + 1
  8. Randomize
  9. For i = 0 To (arrlen-1)*2 '随机交换若干段落的位置,循环次数设大一些交换得更彻底
  10.     Rnd1 = Int(Rnd() * arrlen)
  11.     Rnd2 = Int(Rnd() * arrlen)
  12.     Temp = arr(Rnd1)
  13.     arr(Rnd1) = arr(Rnd2)
  14.     arr(Rnd2) = Temp
  15. Next
  16. str = Join(arr, vbCrLf & vbCrLf)
  17. MsgBox(str)
复制代码

作者: fanfande    时间: 2011-5-31 22:38

谢谢大家!几个测试下来都成功的




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