Board logo

标题: [文本处理] [已解决]批处理怎样获取文本内容显示并自定义替换? [打印本页]

作者: lateol    时间: 2013-3-12 12:57     标题: [已解决]批处理怎样获取文本内容显示并自定义替换?

本帖最后由 lateol 于 2013-3-14 12:28 编辑

如当前目录有XX个txt
每个txt 里都有如下字符串:S3000 S3500 S4000 S4500.....等
如何查找到文本 显示字符后面的数值并替换。
一个txt里 可能有多个多个这样的值 希望显示的时候能以 最小值~最大值显示
如:最小值:S3000 ~最大值:S3500

我的思路如下:
查找当前abc文件夹里所有txt文本内容,查找到如以上的值:S3000 S3500 S4000 S4500 并显示
进行逐个修改:如
=======================
(文件名)1.txt         (查找到的S值) 最小值:S3000 ~最大值:S3500

请输入要把以上的值统一替换为:xxxx
========================
之后就把 文本内容的S3000至S3500 全部替换为xxxxx
不知能都实现这样类型处理。
作者: wankoilz    时间: 2013-3-12 13:19

传个附件来看看吧
作者: BAT-VBS    时间: 2013-3-12 21:05

  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /f %%a in ('findstr "^S" a.txt') do (
  4.     set str=%%a
  5.     set str=!str:M03=!
  6.     echo,!str!
  7. )
  8. pause
复制代码

作者: wankoilz    时间: 2013-3-12 22:55

我觉得楼主的要求用vbs实现起来稳妥点,加上了排序显示功能,看起来有点臃肿。
搜索匹配的是:S后面跟几个数字和M03
把vbs放到待处理txt文件一起运行
  1. Option Explicit
  2. Dim FSO,file,ofile,strText
  3. Set FSO=CreateObject("scripting.filesystemobject")
  4. For Each file In FSO.GetFolder(".").Files
  5.     If LCase(FSO.GetExtensionName(file))="txt" Then
  6. Set ofile=FSO.OpenTextFile(file,1)
  7. strText=ofile.ReadAll():ofile.Close
  8. Set ofile=FSO.OpenTextFile(file,2)
  9. ofile.Write(ShowAndReplace(strText,file.Name))
  10. ofile.Close
  11.     End If
  12. Next
  13. WScript.Echo "处理结束!"
  14. Function ShowAndReplace(str,filename)
  15. Dim Matches,Match
  16. Dim i,j,intCount,dicTmp,strTmp,strShow,strSource
  17.     With CreateObject("vbscript.regexp")
  18.         .Global=True
  19.         .IgnoreCase=True
  20.         .Multiline=True
  21.         .pattern="S[1-9]\d*(?=M03)"
  22.         If  .Test(str)=True Then
  23.             Set Matches=.Execute(str)
  24.             Set dicTmp=CreateObject("scripting.dictionary")
  25.             For Each Match In Matches
  26.                 intCount=intCount+1
  27.                 dicTmp.Add intCount,Match
  28.             Next
  29.             '排序
  30.             For i=1 To dicTmp.Count-1
  31.                 For j=i+1 To dicTmp.Count
  32.                     If dicTmp.Item(i)>dicTmp.Item(j) Then
  33.                         strTmp=dicTmp.Item(i)
  34.                         dicTmp.Item(i)=dicTmp.Item(j)
  35.                         dicTmp.Item(j)=strTmp
  36.                     End If
  37.                 Next
  38.             Next
  39.         For i=1 To dicTmp.Count
  40.             strShow=strShow&dicTmp.Item(i)&vbCrLf
  41.         Next      
  42.         strSource=InputBox(strShow,filename&"的搜索结果,请输入替换值:")
  43.         ShowAndReplace=.Replace(str,strSource)
  44.     Else
  45.         ShowAndReplace=str
  46.     End If
  47.     End With
  48. End Function
复制代码

作者: lateol    时间: 2013-3-13 12:33

本帖最后由 lateol 于 2013-3-13 13:25 编辑

回复 5# BAT-VBS
试了一下 可以查找到并显示。但是显示出来的变量 如何再用来替换呢。
如:
这个文本内有 S3000 S3500 S3000
这三个变量 然后把他们全部一次修改 就如 wankoilz  写的vbs替换方式。
能实现吗?
作者: wankoilz    时间: 2013-3-13 12:59

是这样吗:
  1. Option Explicit
  2. Dim FSO,file,ofile,strText
  3. Set FSO=CreateObject("scripting.filesystemobject")
  4. For Each file In FSO.GetFolder(".").Files
  5.     If LCase(FSO.GetExtensionName(file))="txt" Then
  6. Set ofile=FSO.OpenTextFile(file,1)
  7. strText=ofile.ReadAll():ofile.Close
  8. Set ofile=FSO.OpenTextFile(file,2)
  9. ofile.Write(ShowAndReplace(strText,file.Name))
  10. ofile.Close
  11.     End If
  12. Next
  13. WScript.Echo "处理结束!"
  14. Function ShowAndReplace(str,filename)
  15. Dim Matches,Match
  16. Dim i,j,intCount,dicTmp,strTmp,strShow,strSource
  17. With CreateObject("vbscript.regexp")
  18.     .Global=True
  19.     .IgnoreCase=True
  20.     .Multiline=True
  21.     .pattern="S[1-9]\d*(?=M03)"
  22.     If  .Test(str)=True Then
  23.         Set Matches=.Execute(str)
  24.         Set dicTmp=CreateObject("scripting.dictionary")
  25.         For Each Match In Matches
  26.             intCount=intCount+1
  27.             dicTmp.Add intCount,Match
  28.         Next
  29.         '排序
  30.         For i=1 To dicTmp.Count-1
  31.             For j=i+1 To dicTmp.Count
  32.                 If dicTmp.Item(i)>dicTmp.Item(j) Then
  33.                     strTmp=dicTmp.Item(i)
  34.                     dicTmp.Item(i)=dicTmp.Item(j)
  35.                     dicTmp.Item(j)=strTmp
  36.                 End If
  37.             Next
  38.         Next
  39.         For i=1 To dicTmp.Count
  40.             strShow=strShow&dicTmp.Item(i)&vbCrLf
  41.         Next
  42.         For i=1 To dicTmp.Count     
  43.             strSource=InputBox(strShow&"请输入要替换 "&dicTmp.Item(i)&" 的值(S+数字):",filename&"的搜索结果")
  44.             str=Replace(str,dicTmp.Item(i),strSource)
  45.         Next
  46.         ShowAndReplace=str
  47.     Else
  48.         ShowAndReplace=str
  49.     End If
  50. End With
  51. End Function
复制代码

作者: lateol    时间: 2013-3-13 13:20

回复 8# wankoilz
第一个 就很好了。 这个好像处理 他是把所有的txt处理后又返回第一个处理下去 一直到每个txt S值替换完。
第一个已经满足了 不过还有一点。就是可以改成子目录*.txt吗  如当前目录abc文件夹内*.txt
还有处理过程 如果不输入值 直接确认或退出的话 他就会替换成空 这个可以修正一下么、
谢谢
作者: wankoilz    时间: 2013-3-13 14:01

你说的子目录问题,把第四行FSO.GetFolder(".")中的"."改成".\abc"就处理子目录abc中的文件了。
点“取消”这个问题确实没考虑到,修改如下:
  1. Option Explicit
  2. Dim FSO,file,ofile,strText
  3. Set FSO=CreateObject("scripting.filesystemobject")
  4. For Each file In FSO.GetFolder(".\abc").Files
  5.     If LCase(FSO.GetExtensionName(file))="txt" Then
  6.         Set ofile=FSO.OpenTextFile(file,1)
  7.         strText=ofile.ReadAll():ofile.Close
  8.         Set ofile=FSO.OpenTextFile(file,2)
  9.         ofile.Write(ShowAndReplace(strText,file.Name))
  10.         ofile.Close
  11.     End If
  12. Next
  13. WScript.Echo "处理结束!"
  14. Function ShowAndReplace(str,filename)
  15. Dim Matches,Match
  16. Dim i,j,intCount,dicTmp,strTmp,strShow,strSource
  17.     With CreateObject("vbscript.regexp")
  18.         .Global=True
  19.         .IgnoreCase=True
  20.         .Multiline=True
  21.         .pattern="S[1-9]\d*(?=M03)"
  22.         If  .Test(str)=True Then
  23.             Set Matches=.Execute(str)
  24.             Set dicTmp=CreateObject("scripting.dictionary")
  25.             For Each Match In Matches
  26.                 intCount=intCount+1
  27.                 dicTmp.Add intCount,Match
  28.             Next
  29.             '排序
  30.             For i=1 To dicTmp.Count-1
  31.                 For j=i+1 To dicTmp.Count
  32.                     If dicTmp.Item(i)>dicTmp.Item(j) Then
  33.                         strTmp=dicTmp.Item(i)
  34.                         dicTmp.Item(i)=dicTmp.Item(j)
  35.                         dicTmp.Item(j)=strTmp
  36.                     End If
  37.                 Next
  38.             Next
  39.             For i=1 To dicTmp.Count
  40.                 strShow=strShow&dicTmp.Item(i)&vbCrLf
  41.             Next
  42.             For i=1 To dicTmp.Count     
  43.                 strSource=InputBox(strShow&"请输入要替换 "&dicTmp.Item(i)&" 的值(S+数字):",filename&"的搜索结果")
  44.                 If strSource<>"" Then
  45.                     str=Replace(str,dicTmp.Item(i),strSource)
  46.                 End If
  47.             Next
  48.             ShowAndReplace=str
  49.         Else
  50.             ShowAndReplace=str
  51.         End If
  52.     End With
  53. End Function
复制代码

作者: lateol    时间: 2013-3-13 17:49

回复 10# wankoilz
出现 直接 处理结束 什么情况?
作者: apang    时间: 2013-3-13 20:30

本帖最后由 apang 于 2013-3-13 23:53 编辑
  1. Dir = "D:\ABC"
  2. Set FSO = CreateObject("Scripting.FileSystemObject")
  3. For Each file in FSO.GetFolder(Dir).Files
  4.    Ext = FSO.GetExtensionName(file)
  5.    If Lcase(Ext) = "txt" Then
  6.       RegEx FSO.OpenTextFile(file,1).ReadAll
  7.    End If
  8. Next
  9. Sub RegEx(Text)
  10.    Set Re = New RegExp
  11.    Re.Global = True
  12.    Re.Pattern = "[Ss][1-9]\d*"
  13.    If Not Re.Test(Text) Then Exit Sub
  14.    For Each Match in Re.Execute(Text)
  15.       ReDim PreServe ar(n)
  16.       ar(n) = Match : n = n + 1
  17.    Next
  18.    
  19.    For i = 0 to Ubound(ar) -1
  20.       For j = i + 1 to Ubound(ar)
  21.          If CInt(Mid(ar(i),2)) > CInt(Mid(ar(j),2)) Then
  22.             Tmp = ar(i) :ar(i) = ar(j) :ar(j) = Tmp
  23.          End If
  24.       Next
  25.    Next
  26.    a = InputBox("最小:" & ar(0) & "~最大:" & ar(UBound(ar)) & _
  27.        vbLf & vbLf & "输入替换后的值:",file.Name,"S1000")
  28.    If IsEmpty(a) Then Exit Sub
  29.    If a = "" Then a = "S1000"
  30.    FSO.OpenTextFile(file,2).Write Re.Replace(Text,a)
  31. End Sub
复制代码
行不行就这样,不想折腾了
作者: wankoilz    时间: 2013-3-13 21:18

直接“处理结束”便是没找到相应的匹配吧。
作者: lateol    时间: 2013-3-13 21:34

本帖最后由 lateol 于 2013-3-13 22:05 编辑

回复 13# wankoilz
作者: lateol    时间: 2013-3-13 21:58

回复 12# apang

试了一下 这样显示不错,一直很喜欢你写的代码。
不过还有两个问题,
1.就是标题栏那里 显示的是整个路劲 直接显示名称就好了
2.还有 那个最大最小值 我处理一下看 好像它都是从上拍到下的。而不是从数值的真实大小显示的。
3.处理是当前目录所有子文件处理 希望设置单一一个子文件夹就好 就如当前目录abc文件夹吧。
不过也很感谢你的帮助。虽然要达到一个满意的处理有点难,不过也学到了很多东西。
作者: lateol    时间: 2013-3-13 22:04

本帖最后由 lateol 于 2013-3-13 22:16 编辑

回复 13# wankoilz

好的 可以了 可不可以再修改一下 修改方式 不用一个文本逐个值的修改了 就像之前那个 直接整个文本修改。
也许你误解了我的意思了吧 是逐个文本修改 不是逐个本文的值修改。这是我跟BAT-VBS 写的bat说的。
替换方式就改成 之前写的就行。 谢谢!
作者: apang    时间: 2013-3-13 23:30

回复 15# lateol


    改了,第一行的文件夹请写绝对路径
作者: wankoilz    时间: 2013-3-14 01:03

6楼不就是一次性修改整个文本的值么……
作者: lateol    时间: 2013-3-14 12:18

回复 18# wankoilz
好吧 我研究一下 谢谢了。
作者: lateol    时间: 2013-3-14 12:25

回复 17# apang

呵呵 谢谢 完美运行。
还有请教一个关于bat的
这短语句
  1. a = InputBox("最小:" & ar(0) & "~最大:" & ar(UBound(ar)) & _
  2.        vbLf & vbLf & "输入替换后的值:",file.Name,"S1000")
复制代码
用bat写:
  1. @echo off
  2. ECHO a = InputBox("最小:" & ar(0) & "~最大:" & ar(UBound(ar)) & _>>abc.vbs
  3. ECHO       vbLf & vbLf & "输入替换后的值:",file.Name,"S1000")>>abc.vbs
复制代码
能把代码完全的 写到vbs里吗? 好像& 不行。有什么好的提议么?。
作者: BAT-VBS    时间: 2013-3-14 12:41

回复 20# lateol


转义
^&




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