Board logo

标题: [文本处理] 【已解决】批处理:如何使用字典的方式,替换文本内的字符串 [打印本页]

作者: 思想之翼    时间: 2023-2-20 10:07     标题: 【已解决】批处理:如何使用字典的方式,替换文本内的字符串

本帖最后由 思想之翼 于 2023-2-20 12:28 编辑

A.txt 作为字典,记录数据10万行,格式如下:
0 0 0 0 0=H C A D D F A
0 0 0 0 1=H C G C E B G
0 0 0 0 2=H C C J H B J
............
............
9 9 9 9 7=C A I I I D A
9 9 9 9 8=I F B B A D G
9 9 9 9 9=E G A J A G G

B.txt 是被替换文本,记录数据有重复,行数不定(小于等于10万行),格式如下:
9 9 9 9 9
9 9 9 9 9
9 9 9 9 7
...........
...........
0 0 0 0 2
0 0 0 0 2
0 0 0 0 0

替换结果如下:
E G A J A G G
E G A J A G G
C A I I I D A
.............
.............
H C C J H B J
H C C J H B J
H C A D D F A

注:下列代码太慢了
bwfr.exe "D:\:00\B.txt" -s -f -argfile:A.txt -dlm:"="
作者: hfxiang    时间: 2023-2-20 11:03

试试gawk( http://bcn.bathome.net/tool/4.1.3/gawk.exe
  1. gawk -F"=" "NR==FNR{A[$1]=$2;next}{print A[$0]}" a.txt b.txt>c.txt
复制代码

作者: terse    时间: 2023-2-20 13:16

文件太大了BAT会吃不住
  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "delims=" %%i in (a.txt) do set "_%%i"
  3. for /f "delims=" %%i in (b.txt) do (
  4.      if defined _%%i (
  5.         echo !_%%i!
  6.      )  else echo;%%i
  7. )
  8. pause
复制代码
JS的
  1. @if (0)==(0) echo off
  2. cscript //nologo //E:JScript "%~0"<"b.txt" "a.txt"
  3. pause&exit
  4. content
  5. @end;
  6. var fso = new ActiveXObject("Scripting.FileSystemObject");
  7. function adoLoadText(filename, charset) {
  8.   var stream, text;
  9.   stream = new ActiveXObject("ADODB.Stream");
  10.   stream.type = 2;
  11.   stream.charset = charset;
  12.   stream.open();
  13.   stream.loadFromFile(filename);
  14.   text = stream.readText(-1);
  15.   stream.close();
  16.   return text;
  17. }
  18. var text = adoLoadText(WScript.Arguments.Item(0), 'utf-8');
  19. var arr = [];
  20. var newfile = 'c.txt';//保存文件
  21. while (!WScript.StdIn.AtEndOfStream){
  22.     var str = WScript.StdIn.Readline();
  23.     var re = new RegExp(str + "=(.+)","i");
  24.     var r = text.match(re)
  25.     arr.push(r?r[1]:str)
  26. }
  27. var f = fso.OpenTextFile(newfile,2,true,false);
  28. f.WriteLine(arr.join('\n'));
  29. f.Close()
复制代码

作者: WHY    时间: 2023-2-20 13:35

Test.ps1,右键使用 PowerShell 运行
  1. $myPath = $MyInvocation.MyCommand.Path -replace '\\[^\\]*$', '\';
  2. $fileA = $myPath + 'a.txt';            #源文本A
  3. $fileB = $myPath + 'b.txt';            #源文本B
  4. $fileC = $myPath + 'c.txt';            #目标文本C
  5. If (![IO.File]::Exists($fileA) -or ![IO.File]::Exists($fileB)){
  6.     echo '源文件不存在';
  7.     [Console]::ReadLine();
  8.     exit;
  9. }
  10. $Hash = New-Object System.Collections.HashTable;                              #HashTable,存放文本A数据
  11. $srA = New-Object System.IO.StreamReader($fileA, [Text.Encoding]::Default);   #读文本A
  12. $srB = New-Object System.IO.StreamReader($fileB, [Text.Encoding]::Default);   #读文本B
  13. $swC = New-Object System.IO.StreamWriter($fileC, $false, [Text.Encoding]::Default); #写文件C
  14. while($srA.Peek() -ge 0){
  15.     $strLine = $srA.ReadLine();           #逐行读文本A
  16.     $arr = $strLine.Split('=', 2);        #用'='分割成数组
  17.     If ($arr.Count -eq 2){
  18.         $key = $arr[0];
  19.         $value = $arr[1];
  20.         If (!$Hash.ContainsKey($key)){
  21.             $Hash.Add($key, $value);      #存入HashTable
  22.         }
  23.     }
  24. }
  25. $srA.Dispose();
  26. $srA.Close();
  27. while($srB.Peek() -ge 0){
  28.     $strLine = $srB.ReadLine();           #逐行读文本B
  29.     If ($Hash.ContainsKey($strLine)){
  30.         $strLine = $Hash[$strLine];       #重新赋值
  31.     }
  32.     $swC.WriteLine($strLine);             #写文件C
  33.     $swC.Flush();
  34. }
  35. $srB.Dispose();
  36. $srB.Close();
  37. $swC.Dispose();
  38. echo 'Done';
  39. [Console]::ReadLine();
复制代码

作者: 思想之翼    时间: 2023-2-20 15:46

本帖最后由 思想之翼 于 2023-2-20 16:08 编辑

感谢大家!
作者: 思想之翼    时间: 2023-2-20 16:09

本帖最后由 思想之翼 于 2023-2-20 16:15 编辑

回复 2# hfxiang

gawk -F"=" "NR==FNR{A[$1]=$2;next}{print A[$0]}" a.txt b.txt>c.txt

若 a.txt 在   D:\00\
    b.txt 在   D:\11\
将 c.txt 写入 D:\22\
如何正确添加路径?恳望不吝指教。
作者: hfxiang    时间: 2023-2-20 16:39

回复 6# 思想之翼
  1. "C:\SoftWare\gawk.exe" -F"=" "NR==FNR{A[$1]=$2;next}{print A[$0]}" "D:\00\a.txt" "D:\11\b.txt">"D:\22\c.txt"
复制代码

作者: 思想之翼    时间: 2023-2-25 20:29

回复 3# terse

感谢帮助!
JS 代码 18行 var text = adoLoadText(WScript.Arguments.Item(0), 'utf-8'); 运行出错,下标越界,代码 800A0009
恳望指点!
作者: terse    时间: 2023-2-25 22:14

回复 8# 思想之翼
WScript.Arguments.Item(0) 这里是a.txt  或者先设置一个变量吧  var file = WScript.Arguments.Item(0) ;查看文件有没有传递进来




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