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

[文本处理] 【已解决】批处理实现多条目多内容同时替换

[复制链接]
发表于 2024-5-18 13:13:40 | 显示全部楼层 |阅读模式
本帖最后由 zhengwei007 于 2024-5-29 16:56 编辑

我有个几千行的源文本text.txt,里面内容大概如下:

  1. a,Recipe: Piece Bone Gaiters    1    59%\\nLeather Helmet Design    1    38%\\nRecipe: Piece Bone Breastplate    1    37%\0
  2. a,Thread    2 - 3    100%\\nRecipe: Piece Bone Gaiters    1    59%\\nHaste Potion    1    19%\0
复制代码
我制作了一个类似字典的东西,也是一个txt,里面分左右两段,中间用逗号分开,逗号左边是要找的内容,逗号右边是要对应替换的内容。样式如下:

  1. \\nLeather Helmet Design    ,\\n测试皮头盔甲   
  2. \\nHaste Potion    ,\\n药水   
  3. \\nRecipe: Piece Bone Breastplate    ,\\n骨头胸甲的制作卷   
复制代码
注:为了保持格式正确且完全匹配,我在每个结尾都加了4个空格,因为源文本就有空格。

我希望能通过批处理执行后,源文本直接保持原格式替换,结果变为如下样式:
a,Recipe: Piece Bone Gaiters    1    59%\\n测试皮头盔甲    1    38%\\n骨头胸甲的制作卷    1    37%\0
a,Thread    2 - 3    100%\\nRecipe: Piece Bone Gaiters    1    59%\\n药水    1    19%\0

请大家帮帮忙,谢谢。
发表于 2024-5-18 15:47:10 | 显示全部楼层
另存为 ANSI 编码的 vbs
  1. f1 = "text.txt"
  2. c1 = "GBK"       '文件编码,可以是 UTF-16 或 UTF-8

  3. f2 = "字典.txt"
  4. c2 = "GBK"

  5. Set oRegExp = CreateObject("VBScript.RegExp")
  6. oRegExp.Global = True
  7. oRegExp.IgnoreCase = True
  8. Set oStream1 = CreateObject("ADODB.Stream")
  9. oStream1.Type = 2
  10. oStream1.Mode = 3
  11. oStream1.Charset = c1
  12. oStream1.Open()
  13. oStream1.LoadFromFile f1
  14. s = oStream1.ReadText()
  15. Set oStream2 = CreateObject("ADODB.Stream")
  16. oStream2.Type = 2
  17. oStream2.Mode = 3
  18. oStream2.Charset = c2
  19. oStream2.Open()
  20. oStream2.LoadFromFile f2
  21. Do
  22.     m = oStream2.ReadText(-2)
  23.     If InStr(m, ",") Then
  24.         m = Split(m, ",", 2)
  25.         m(0) = RePlace(m(0), "", "\")
  26.         oRegExp.Pattern = m(0)
  27.         s = oRegExp.Replace(s, m(1))
  28.     End If
  29. Loop Until oStream2.EOS
  30. oStream1.Close()
  31. oStream1.Open()
  32. oStream1.WriteText s
  33. oStream1.SaveToFile f1, 2
  34. wsh.Echo "ok"
复制代码
 楼主| 发表于 2024-5-18 17:35:23 | 显示全部楼层
另存为 ANSI 编码的 vbs
czjt1234 发表于 2024-5-18 15:47


你好,我执行完后,text.txt文件里面有小方框,感觉像是编码不对。我已经把两个文件全部改成ANSI编码了还是不行。

文件我打包上传了,请您帮忙看下。谢谢。

链接: https://pan.baidu.com/s/1kLUnWvjviDh2ADWtva7VNQ 提取码: sisp 复制这段内容后打开百度网盘手机App,操作更方便哦
--来自百度网盘超级会员v9的分享
发表于 2024-5-18 19:46:07 | 显示全部楼层
win7x64,下载测试正常,没发现有小方框
源文件编码就是GBK

vbs处理大文件还是不行,太慢,等第三方程序来看看吧
发表于 2024-5-18 22:04:31 | 显示全部楼层
字典 2.txt源文件 1.txt
输出 3.txt
  1. @echo off
  2. cd /d "%~dp0"
  3. setlocal enabledelayedexpansion
  4. for /f "useback tokens=1-2 delims=," %%a in ("2.txt") do (
  5.         set "str=%%~nxa"
  6.         set "str=!str::= !"
  7.         set "#"!str!"=%%~nxb"
  8. )
  9. (for /f "useback delims=" %%a in ("1.txt") do (
  10.         set "str="%%a""
  11.         set "str=!str:    =" "!"
  12.         setlocal
  13.         for %%b in (!str!) do (
  14.                 for /f "tokens=1* delims=" %%c in ("%%~b") do (
  15.                         if "%%d" equ "" (
  16.                                 set "x=!x!%%c    "
  17.                         ) else (
  18.                                 set "d=%%d"
  19.                                 set "d=!d::= !"
  20.                                 if not defined #"!d!" (
  21.                                         if "%%d" equ "0" (
  22.                                                 set "x=!x!%%c\%%d    "
  23.                                         ) else (
  24.                                                 set "x=!x!%%c\\%%d    "
  25.                                         )
  26.                                 ) else (
  27.                                         for /f "delims=" %%e in ("#"!d!"") do (
  28.                                                 set "x=!x!%%c\\!%%e!    "
  29.                                         )
  30.                                 )
  31.                         )
  32.                 )
  33.         )
  34.         echo !x:~0,-4!
  35.         endlocal
  36. ))>3.txt
  37. endlocal
  38. pause
复制代码


如果字典也是几千行,代码效率低,不适用。如果有其它问题,请把源文件上传到网盘。
发表于 2024-5-18 22:27:10 | 显示全部楼层
刚看到3楼,9000多行的字典,不知道超限制没,跑了五六分钟。结果 https://f.ws59.cn/f/e553x76waut
 楼主| 发表于 2024-5-19 00:32:08 | 显示全部楼层


你发的地址,打开后也有小方框。
我自己运行后的,也有小方框,还是编码不对?
发表于 2024-5-19 01:03:20 | 显示全部楼层
回复 7# zhengwei007


   可能是软件原因,被错误识别了吧。换用其它的文本软件打开试试。
发表于 2024-5-19 07:39:20 | 显示全部楼层
保存为gbk或ansi的bat
仅针对3楼内容的格式
源文本跟字典txt编码全部gbk/ansi
替换后会生成新文件,编码gbk/ansi

  1. @{}#? 2>nul&pause&powershell -c "gc -literalpath '%~f0'|out-string|iex"&exit/b
  2. [console]::writeline("`r`nrunning")

  3. #$thehash=new-object hashtable
  4. $thehash=@{}

  5. gc '字典.txt' |foreach{
  6. $str=$_ -split '    ,'
  7. if($thehash.ContainsKey($str[0])){
  8. $thehash[$str[0]]=$str[1].trimend()
  9. }else{
  10. $thehash.add($str[0],$str[1].trimend())
  11. }
  12. }

  13. gc 'text.txt' |foreach{
  14. $aaa=$_.replace('\\n','    \\n')
  15. $str=($aaa -split '    ' |foreach{if($thehash.ContainsKey($_)){$thehash[$_]}else{$_}}) -join '    '
  16. $str.replace('    \\n','\\n')
  17. } |sc the-new-text.txt

  18. [console]::writeline("`r`ndone")
  19. cmd /c pause
复制代码
发表于 2024-5-19 07:40:53 | 显示全部楼层
回复 7# zhengwei007


    看右下角 , 编码被识别成 utf-8 了
发表于 2024-5-19 15:20:29 | 显示全部楼层
本帖最后由 hfxiang 于 2024-5-24 10:32 编辑

回复 1# zhengwei007

命令行窗口下执行如下gawk(http://bcn.bathome.net/tool/4.1.0/gawk.exe)脚本可实现:

  1. gawk "FNR==NR{split($0, a, /[^,]+|(\042[^\042]+\042)/,m);r[m[1]]=m[2]}FNR<NR{split($0, a, /\\\\[^\\0-9]+    /,m);printf a[1];for(i in m){if(!r[m[i]])r[m[i]]=m[i];printf("%s%s",r[m[i]],a[i+1])};print""}" "字典.txt" "text.txt">"text_new.txt"
复制代码
效率也是杠杠的
(抱歉,原脚本有遗漏,现已修正)
发表于 2024-5-19 16:29:01 | 显示全部楼层
本帖最后由 aloha20200628 于 2024-5-19 18:38 编辑

回复 1# zhengwei007

用jscript和python两个版本分别测试了楼主提供的示例文件》text.txt(ansi编码), 字典.txt(ansi/gb2312编码)
前者用时约50秒,后者用时约20秒,测试系统硬件指标是intel i7-5500U
以下代码存为test.bat运行,生成替换结果文件为 text.new.txt(ansi/gb2312编码)

  1. @set @v=1 //&(cscript /e:jscript "%~f0")&exit/b
  2. //
  3. fso = new ActiveXObject('Scripting.FileSystemObject');
  4. fp = fso.OpenTextFile('字典.txt'), linesD = fp.readall().split('\r\n'), fp.close();
  5. fp = fso.OpenTextFile('text.txt'), lineT = fp.readall(), fp.close();
  6. fp = fso.OpenTextFile('text.new.txt',2,true);
  7. for (var kv,re,i=0,l=linesD.length; i<l; i++) {
  8.         kv = linesD[i].split(','), k = trim(kv[0]), v = trim(kv[1]);
  9.         eval('re=/'+k+'/gi;'), lineT = lineT.replace(re, v);
  10. }
  11. fp.write(lineT), fp.close(), WSH.quit();
  12. //
  13. function trim (s) { return s.replace(/(^\s*)|(\s*$)/g,''); }
复制代码
如果楼主已经预装了python系统,可将以下代码存为test.py,直接在命令行运行,生成替换结果文件为 text.new.txt(ansi/gb2312编码)

  1. #encoding=gbk
  2. import re
  3. with open('text.txt', 'r', -1) as fr:
  4.         tLine = fr.read()
  5. with open('字典.txt', 'r', -1) as fr:
  6.         dLines = fr.readlines()
  7. for d in dLines:
  8.         kv = d.split(',')
  9.         k, v = kv[0].strip(), kv[1].strip()
  10.         tLine = re.sub(k, v, tLine, flags=re.I|re.S)
  11. with open('text.new.txt', 'w', -1) as fw:
  12.         fw.write(tLine)
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-3-18 01:19 , Processed in 0.021477 second(s), 8 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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