找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 32539|回复: 13

[文本处理] [已解决]批处理怎样随机打乱文本段落?

[复制链接]
发表于 2011-5-27 19:05:44 | 显示全部楼层 |阅读模式
本帖最后由 fanfande 于 2011-5-31 22:39 编辑

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

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


段落的标志是

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

评分

参与人数 1PB +2 收起 理由
zm900612 + 2 感谢给帖子标题标注[已解决]字样

查看全部评分

发表于 2011-5-27 19:09:45 | 显示全部楼层
楼主所说的段落概念是什么,一段最多有多少个字符?
 楼主| 发表于 2011-5-27 20:51:41 | 显示全部楼层
2# batman


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

比如一个文档里面有5段,那么让他们随机排列就是p55排列组合里面随机一个!
发表于 2011-5-27 21:03:22 | 显示全部楼层
段落短而且不含“!”号可以:
  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
复制代码
发表于 2011-5-27 21:08:26 | 显示全部楼层
段落长,或者含有特殊字符!也都有办法处理,不过耗时大增。
而段落中若既含!,又含%,那就比较麻烦了...
发表于 2011-5-27 21:10:33 | 显示全部楼层
那如何判断为一段,有什么标志?
发表于 2011-5-27 21:15:08 | 显示全部楼层
我理解为,行开头空格的就是一段的开始。
发表于 2011-5-27 21:25:36 | 显示全部楼层
希望楼主在顶楼更新一下,贴出前后对比的样本,以作范例
发表于 2011-5-28 02:12:44 | 显示全部楼层
本帖最后由 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:02 | 显示全部楼层
用临时文件,一个段落一个文件,再随机合并这些文件。
发表于 2011-5-29 23:30:58 | 显示全部楼层
本帖最后由 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:开始看错题意,还写了遍历函数并改写了原文本。。。
发表于 2011-5-30 09:59:47 | 显示全部楼层
本帖最后由 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里面!

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


段落的标志是


用批处理做吗……  ? 哈,我去工作了,好忙。
发表于 2011-5-30 19:10:39 | 显示全部楼层

  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)
复制代码
 楼主| 发表于 2011-5-31 22:38:59 | 显示全部楼层
谢谢大家!几个测试下来都成功的
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-17 12:45 , Processed in 0.022914 second(s), 9 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表