标题: [文本处理] 【已解决】批处理实现多条目多内容同时替换 [打印本页]
作者: zhengwei007 时间: 2024-5-18 13:13 标题: 【已解决】批处理实现多条目多内容同时替换
本帖最后由 zhengwei007 于 2024-5-29 16:56 编辑
我有个几千行的源文本text.txt,里面内容大概如下:- a,Recipe: Piece Bone Gaiters 1 59%\\nLeather Helmet Design 1 38%\\nRecipe: Piece Bone Breastplate 1 37%\0
- a,Thread 2 - 3 100%\\nRecipe: Piece Bone Gaiters 1 59%\\nHaste Potion 1 19%\0
复制代码
我制作了一个类似字典的东西,也是一个txt,里面分左右两段,中间用逗号分开,逗号左边是要找的内容,逗号右边是要对应替换的内容。样式如下:- \\nLeather Helmet Design ,\\n测试皮头盔甲
- \\nHaste Potion ,\\n药水
- \\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
请大家帮帮忙,谢谢。
作者: czjt1234 时间: 2024-5-18 15:47
另存为 ANSI 编码的 vbs- f1 = "text.txt"
- c1 = "GBK" '文件编码,可以是 UTF-16 或 UTF-8
-
- f2 = "字典.txt"
- c2 = "GBK"
-
- Set oRegExp = CreateObject("VBScript.RegExp")
- oRegExp.Global = True
- oRegExp.IgnoreCase = True
- Set oStream1 = CreateObject("ADODB.Stream")
- oStream1.Type = 2
- oStream1.Mode = 3
- oStream1.Charset = c1
- oStream1.Open()
- oStream1.LoadFromFile f1
- s = oStream1.ReadText()
- Set oStream2 = CreateObject("ADODB.Stream")
- oStream2.Type = 2
- oStream2.Mode = 3
- oStream2.Charset = c2
- oStream2.Open()
- oStream2.LoadFromFile f2
- Do
- m = oStream2.ReadText(-2)
- If InStr(m, ",") Then
- m = Split(m, ",", 2)
- m(0) = RePlace(m(0), "\", "\\")
- oRegExp.Pattern = m(0)
- s = oRegExp.Replace(s, m(1))
- End If
- Loop Until oStream2.EOS
- oStream1.Close()
- oStream1.Open()
- oStream1.WriteText s
- oStream1.SaveToFile f1, 2
- wsh.Echo "ok"
复制代码
作者: zhengwei007 时间: 2024-5-18 17:35
另存为 ANSI 编码的 vbs
czjt1234 发表于 2024-5-18 15:47
你好,我执行完后,text.txt文件里面有小方框,感觉像是编码不对。我已经把两个文件全部改成ANSI编码了还是不行。
文件我打包上传了,请您帮忙看下。谢谢。
链接: https://pan.baidu.com/s/1kLUnWvjviDh2ADWtva7VNQ 提取码: sisp 复制这段内容后打开百度网盘手机App,操作更方便哦
--来自百度网盘超级会员v9的分享
作者: czjt1234 时间: 2024-5-18 19:46
win7x64,下载测试正常,没发现有小方框
源文件编码就是GBK
vbs处理大文件还是不行,太慢,等第三方程序来看看吧
作者: 77七 时间: 2024-5-18 22:04
字典 2.txt源文件 1.txt
输出 3.txt
- @echo off
- cd /d "%~dp0"
- setlocal enabledelayedexpansion
- for /f "useback tokens=1-2 delims=,\" %%a in ("2.txt") do (
- set "str=%%~nxa"
- set "str=!str::= !"
- set "#"!str!"=%%~nxb"
- )
- (for /f "useback delims=" %%a in ("1.txt") do (
- set "str="%%a""
- set "str=!str: =" "!"
- setlocal
- for %%b in (!str!) do (
- for /f "tokens=1* delims=\" %%c in ("%%~b") do (
- if "%%d" equ "" (
- set "x=!x!%%c "
- ) else (
- set "d=%%d"
- set "d=!d::= !"
- if not defined #"!d!" (
- if "%%d" equ "0" (
- set "x=!x!%%c\%%d "
- ) else (
- set "x=!x!%%c\\%%d "
- )
- ) else (
- for /f "delims=" %%e in ("#"!d!"") do (
- set "x=!x!%%c\\!%%e! "
- )
- )
- )
- )
- )
- echo !x:~0,-4!
- endlocal
- ))>3.txt
- endlocal
- pause
复制代码
如果字典也是几千行,代码效率低,不适用。如果有其它问题,请把源文件上传到网盘。
作者: 77七 时间: 2024-5-18 22:27
刚看到3楼,9000多行的字典,不知道超限制没,跑了五六分钟。结果 https://f.ws59.cn/f/e553x76waut
作者: zhengwei007 时间: 2024-5-19 00:32
你发的地址,打开后也有小方框。
我自己运行后的,也有小方框,还是编码不对?
作者: 77七 时间: 2024-5-19 01:03
回复 7# zhengwei007
可能是软件原因,被错误识别了吧。换用其它的文本软件打开试试。
作者: Five66 时间: 2024-5-19 07:39
保存为gbk或ansi的bat
仅针对3楼内容的格式
源文本跟字典txt编码全部gbk/ansi
替换后会生成新文件,编码gbk/ansi- @{}#? 2>nul&pause&powershell -c "gc -literalpath '%~f0'|out-string|iex"&exit/b
- [console]::writeline("`r`nrunning")
-
- #$thehash=new-object hashtable
- $thehash=@{}
-
- gc '字典.txt' |foreach{
- $str=$_ -split ' ,'
- if($thehash.ContainsKey($str[0])){
- $thehash[$str[0]]=$str[1].trimend()
- }else{
- $thehash.add($str[0],$str[1].trimend())
- }
- }
-
- gc 'text.txt' |foreach{
- $aaa=$_.replace('\\n',' \\n')
- $str=($aaa -split ' ' |foreach{if($thehash.ContainsKey($_)){$thehash[$_]}else{$_}}) -join ' '
- $str.replace(' \\n','\\n')
- } |sc the-new-text.txt
-
- [console]::writeline("`r`ndone")
- cmd /c pause
复制代码
作者: Five66 时间: 2024-5-19 07:40
回复 7# zhengwei007
看右下角 , 编码被识别成 utf-8 了
作者: hfxiang 时间: 2024-5-19 15:20
本帖最后由 hfxiang 于 2024-5-24 10:32 编辑
回复 1# zhengwei007
在命令行窗口下执行如下gawk(http://bcn.bathome.net/tool/4.1.0/gawk.exe)脚本可实现:- 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"
复制代码
效率也是杠杠的
(抱歉,原脚本有遗漏,现已修正)
作者: aloha20200628 时间: 2024-5-19 16:29
本帖最后由 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编码)- @set @v=1 //&(cscript /e:jscript "%~f0")&exit/b
- //
- fso = new ActiveXObject('Scripting.FileSystemObject');
- fp = fso.OpenTextFile('字典.txt'), linesD = fp.readall().split('\r\n'), fp.close();
- fp = fso.OpenTextFile('text.txt'), lineT = fp.readall(), fp.close();
- fp = fso.OpenTextFile('text.new.txt',2,true);
- for (var kv,re,i=0,l=linesD.length; i<l; i++) {
- kv = linesD[i].split(','), k = trim(kv[0]), v = trim(kv[1]);
- eval('re=/'+k+'/gi;'), lineT = lineT.replace(re, v);
- }
- fp.write(lineT), fp.close(), WSH.quit();
- //
- function trim (s) { return s.replace(/(^\s*)|(\s*$)/g,''); }
复制代码
如果楼主已经预装了python系统,可将以下代码存为test.py,直接在命令行运行,生成替换结果文件为 text.new.txt(ansi/gb2312编码)- #encoding=gbk
- import re
- with open('text.txt', 'r', -1) as fr:
- tLine = fr.read()
- with open('字典.txt', 'r', -1) as fr:
- dLines = fr.readlines()
- for d in dLines:
- kv = d.split(',')
- k, v = kv[0].strip(), kv[1].strip()
- tLine = re.sub(k, v, tLine, flags=re.I|re.S)
- with open('text.new.txt', 'w', -1) as fw:
- fw.write(tLine)
复制代码
欢迎光临 批处理之家 (http://bathome.net./) |
Powered by Discuz! 7.2 |