Board logo

标题: [文本处理] [已解决]求助批处理:两个文本文件之间复杂的查找替换 [结束] [打印本页]

作者: dyfgkxue    时间: 2022-3-26 11:17     标题: [已解决]求助批处理:两个文本文件之间复杂的查找替换 [结束]

本帖最后由 dyfgkxue 于 2022-3-26 16:10 编辑

有两个文本文件,有一定的关联,A文本中有很多以下类似内容:
TitleList.Title.1=欢迎使用 FontCreator 14
TitleList.Level.1=1
TitleList.Url.1=welcometothefontcreator.html
TitleList.Icon.1=0
TitleList.Status.1=0
TitleList.Keywords.1=功能
TitleList.ContextNumber.1=1001
TitleList.ApplyTemp.1=0
TitleList.Expanded.1=0
TitleList.Kind.1=0
TitleList.Title.2=What's New in FontCreator 14
TitleList.Level.2=1
TitleList.Url.2=whatisnew.html
TitleList.Icon.2=0
TitleList.Status.2=0
TitleList.Keywords.2=New Features
TitleList.ContextNumber.2=1002
TitleList.ApplyTemp.2=0
TitleList.Expanded.2=0
TitleList.Kind.2=0

B文本中有很多关联内容:
//Generated by CHM Editor (https://chmeditor.com)

#define IDH_WELCOMETOTHEFONTCREATOR_HTML                           301 //welcometothefontcreator.html
#define IDH_WHATISNEW_HTML                                         303 //whatisnew.html
#define IDH_FC_GETTING-STARTED-WITH-FONTCREAT_HTML                 361 //fc_getting-started-with-fontcreat.html
#define IDH_TECHNICALSUPPORT_HTML                                  292 //technicalsupport.html
#define IDH_REGISTRATION_HTML                                      230 //registration.html
#define IDH_CREDITS_HTML                                           1050 //credits.html
#define IDH_YOURFIRSTFONT--ABRIEFTUTORIAL_HTML                     115 //yourfirstfont--abrieftutorial.html
#define IDH_EDITAGLYPH-CHARACTER3_HTML                             262 //editaglyph-character3.html
#define IDH_EDITAGLYPH-CHARACTERA_HTML                             118 //editaglyph-charactera.html

批处理实现如下效果,举例说明:把A文本里“TitleList.Url.1=welcometothefontcreator.html”对应的“TitleList.ContextNumber.1=1001”(以 .1、.2、.N 为对应关系) 中的 "1001”,替换为B文本 “301 //welcometothefontcreator.html”(以相同的xxxx.html为对应管理)中的“301”,其它依次类推。需保证A文本内容行次不变。恳请大佬赐教!谢谢各位了!——完美的批处理及前两名帮助最大的予以打赏^_^
作者: went    时间: 2022-3-26 12:09

本帖最后由 went 于 2022-3-26 15:35 编辑

test.bat,A.txt,B.txt均保存为ansi编码
  1. @echo off & cd /d "%~dp0"
  2. setlocal enabledelayedexpansion
  3. REM txt设置
  4. set "t1=A.txt"
  5. set "t2=B.txt"
  6. for %%i in ("%t1%") do set "new_file=%%~ni_NEW%%~xi"
  7. REM 替换文件
  8. (
  9. for /f "usebackq delims=" %%i in ("%t1%") do (
  10. for /f "tokens=1* delims==" %%a in ("%%i") do (
  11. set "a=%%a"
  12. REM TitleList.ContextNumber查找并替换
  13. if "!a:~0,24!"=="TitleList.ContextNumber." (
  14. ( for /f "tokens=3" %%c in ('findstr /e /C:"\/\/!ctx%%~xa!" "%t2%" 2^>nul') do echo %%a=%%c ) || echo %%i
  15. ) else (
  16. REM TitleList.Url保存*.html
  17. if "!a:~0,14!"=="TitleList.Url." set "ctx%%~xa=%%b"
  18. echo %%i
  19. )
  20. )
  21. )
  22. ) > "%new_file%"
  23. pause&exit
复制代码

作者: dyfgkxue    时间: 2022-3-26 13:48

测试了一下,基本好用!
1.就是有个问题:原A文本中的“TitleList.Url.29=XXXXXX.html”,假如“XXXXXX.html”为空,即:“TitleList.Url.29=”,在新生成的A文本里,原“TitleList.ContextNumber.29=XXX”不会被保留,我希望保留!
2.能不能保留原A文本,新生成的A文本,名为A_New.txt
你的微信号是多少?我给你打赏!说到做到。
作者: went    时间: 2022-3-26 14:17

回复 3# dyfgkxue


    2楼已更新,点我签名
作者: Batcher    时间: 2022-3-26 14:32

回复 1# dyfgkxue
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. cd /d "%~dp0"
  4. (for /f "delims=" %%i in ('type "A.txt"') do (
  5.     for /f "tokens=1* delims==" %%a in ("%%i") do (
  6.         set "Column1=%%a"
  7.         if "!Column1:~0,14!" equ "TitleList.Url." (
  8.             set "Column2%%~xa=%%b"
  9.             echo,%%i
  10.         ) else if "!Column1:~0,24!" equ "TitleList.ContextNumber." (
  11.             if "!Column2%%~xa!" neq "" (
  12.                 for /f "tokens=3" %%c in ('findstr /e "\/\/!Column2%%~xa!" "B.txt"') do (
  13.                     echo,%%a=%%c
  14.                 )
  15.             ) else (
  16.                 echo,%%i
  17.             )
  18.         ) else (
  19.             echo,%%i
  20.         )
  21.     )
  22. ))>"A_New.txt"
复制代码

作者: dyfgkxue    时间: 2022-3-26 14:50

还有点问题,需要完善,可能需要将//后面的XXXXX.html精确匹配:
#define IDH_INTRODUCTION_HTML                                      266 //introduction.html
#define IDH_COMPOSITEGLYPHSINTRODUCTION_HTML                       137 //compositeglyphsintroduction.html
#define IDH_SIMPLEGLYPHSINTRODUCTION_HTML                          136 //simpleglyphsintroduction.html
#define IDH_COLORGLYPHSINTRODUCTION_HTML                           328 //colorglyphsintroduction.html
上述四行都包含introduction.html,都把它写入新A文本的
TitleList.Url.52=introduction.html
....
TitleList.ContextNumber.52=266
TitleList.ContextNumber.52=136
TitleList.ContextNumber.52=137
TitleList.ContextNumber.52=328
.....
作者: dyfgkxue    时间: 2022-3-26 14:52

如何加你的QQ,加你的746531439号,被拒绝
作者: went    时间: 2022-3-26 15:04

本帖最后由 went 于 2022-3-26 15:11 编辑

精确匹配,将14行的
  1. "!ctx%%~xa!"
复制代码
替换成
  1. /C:"\/\/!ctx%%~xa!"
复制代码
感谢支持
作者: dyfgkxue    时间: 2022-3-26 15:22

回复 5# Batcher


    试了您的批处理,基本很OK!但有个小问题,CMD界面报错:“系统找不到指定路径”,其实批处理还在继续运行(开始两次不知道,迅速关掉CMD,结果新A文本还没完全生成),CMD窗口自己关闭后,会生成完整的新A文本,很完美!谢谢!
作者: zaqmlp    时间: 2022-3-26 15:26

  1. <# :
  2. cls&echo off&cd /d "%~dp0"
  3. powershell -NoProfile -ExecutionPolicy bypass "[IO.File]::ReadAllText(\"%~f0\",[Text.Encoding]::GetEncoding('GB2312'))|Invoke-Expression"
  4. pause
  5. exit
  6. #>
  7. $file1="A.txt";
  8. $file2="B.txt";
  9. if(-not (test-path -literal $file1)){write-host ('"'+$file1+'" not found');exit;}
  10. if(-not (test-path -literal $file2)){write-host ('"'+$file2+'" not found');exit;}
  11. $enc=[Text.Encoding]::GetEncoding('GB2312');
  12. $dic=New-Object 'System.Collections.Generic.Dictionary[string, string]';
  13. $text2=[IO.File]::ReadAllLines($file2, $enc);
  14. for($i=0;$i -lt $text2.length;$i++){
  15.     $m=[regex]::match($text2[$i], '(\d+) *//([^\r\n]+)');
  16.     if($m.Success){
  17.         $k=$m.groups[2].value.ToLower();
  18.         if(-not $dic.ContainsKey($k)){$dic.add($k, $m.groups[1].value);}
  19.     }
  20. }
  21. $text1=[IO.File]::ReadAllText($file1, $enc);
  22. $text1=[regex]::replace($text1, '(TitleList.Url.\d+=([^\r\n]+)[\s\S+]*?TitleList.ContextNumber.\d+=)[^\r\n]*', {
  23.     param($m);
  24.     $k=$m.groups[2].value.ToLower();
  25.     if($dic.ContainsKey($k)){
  26.         $m.groups[1].value+$dic[$k];
  27.     }else{$m.groups[0].value;}
  28. });
  29. [IO.File]::WriteAllText($file1, $text1, $enc);
复制代码

作者: dyfgkxue    时间: 2022-3-26 15:30

本帖最后由 dyfgkxue 于 2022-3-26 15:33 编辑
精确匹配,将14行的替换成感谢支持
went 发表于 2022-3-26 15:04



    是不是不带 /c: ?   ——应该带的, /c: 是个参数!
作者: went    时间: 2022-3-26 15:35

回复 11# dyfgkxue


    2楼更新了,直接复制吧
作者: dyfgkxue    时间: 2022-3-26 15:43

本帖最后由 dyfgkxue 于 2022-3-26 15:47 编辑

回复 12# went


    谢谢!现在很完美了!


感谢:went、Batcher、zaqmlp !你们的代码有空儿,仔细学习学习,让我自己写,估计得捣鼓一个星期~
另外,zaqmlp的代码是什么语言?C?
作者: Batcher    时间: 2022-3-26 15:59

回复 13# dyfgkxue


10楼代码是用BAT调用的PowerShell脚本
有兴趣的话可以看看相关的教程:
http://bbs.bathome.net/thread-26220-1-1.html
作者: dyfgkxue    时间: 2022-3-27 15:04

本帖最后由 dyfgkxue 于 2022-3-27 15:25 编辑

三个版本 Bat 的评价:
一、went 版本
原 A 文本的空行,在新 A 文本中没有保留,想原样保留;新 A 文本中新生成的 TitleList.ContextNumber.2=1002 的“1002”后面有个空格。【注:把第14行的 do echo %%a=%%c ),右括号前面的空格删除即可。】
二、Batcher 版本
原 A 文本的空行,在新 A 文本中没有保留,想原样保留;若操作目录的目录名中任意位置有个英文叹号 !,Cmd窗口中会报“系统中找不到指定的路径”,但不影响结果。
三、zaqmlp 版本
最完美,以上两点小问题,都不存在。
作者: Batcher    时间: 2022-3-27 16:04

回复 15# dyfgkxue
  1. @echo off
  2. cd /d "%~dp0"
  3. setlocal enabledelayedexpansion
  4. (for /f "tokens=1* delims=:" %%h in ('findstr /n .* "A.txt"') do (
  5.     if "%%i" neq "" (
  6.         for /f "tokens=1* delims==" %%a in ("%%i") do (
  7.             set "Column1=%%a"
  8.             if "!Column1:~0,14!" equ "TitleList.Url." (
  9.                 set "Column2%%~xa=%%b"
  10.                 echo,%%i
  11.             ) else if "!Column1:~0,24!" equ "TitleList.ContextNumber." (
  12.                 if "!Column2%%~xa!" neq "" (
  13.                     for /f "tokens=3" %%c in ('findstr /e "\/\/!Column2%%~xa!" "B.txt"') do (
  14.                         echo,%%a=%%c
  15.                     )
  16.                 ) else (
  17.                     echo,%%i
  18.                 )
  19.             ) else (
  20.                 echo,%%i
  21.             )
  22.         )
  23.     ) else (
  24.         echo,
  25.     )
  26. ))>"A_New.txt"
复制代码

作者: dyfgkxue    时间: 2022-3-27 19:53

感谢!感谢!很完美了~~




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