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

[文本处理] 【已解决】求助BAT代码中提取单个文本中几个关键词写到csv

[复制链接]
发表于 2024-2-28 14:02:32 | 显示全部楼层 |阅读模式
本帖最后由 zhengwei007 于 2024-2-28 23:38 编辑

代码如下,是以<skillTree>开头,</skillTree>结尾的多组文件,希望通过批处理对单个文件内的内容进行整理。
  1.         <!-- Human Fighter -->
  2.         <skillTree type="classSkillTree" classId="0">
  3.                 <!-- Confirmed CT2.5 -->
  4.                 <skill skillName="Lucky" skillId="194" skillLvl="1" getLevel="1" autoGet="true" />
  5.                 <skill skillName="Expertise D" skillId="239" skillLvl="1" getLevel="20" autoGet="true" />
  6.         </skillTree>
  7.         <!-- Doomcryer -->
  8.         <skillTree type="classSkillTree" classId="116" parentClassId="52">
  9.                 <!-- Confirmed CT2.5 and Updated to H5 -->
  10.                 <skill skillName="Wisdom" skillId="328" skillLvl="1" getLevel="76" levelUpSp="8300000" learnedByNpc="true" />
  11.                 <skill skillName="Health" skillId="329" skillLvl="1" getLevel="76" levelUpSp="8300000" learnedByNpc="true" />
  12.                 <skill skillName="Sigil Mastery" skillId="935" skillLvl="1" getLevel="76" levelUpSp="8300000" learnedByNpc="true" />
  13.         </skillTree>
  14.         <!-- Silver Ranger -->
  15.         <skillTree type="classSkillTree" classId="24" parentClassId="22">
  16.                 <!-- Confirmed CT2.5 -->
  17.                 <skill skillName="Divine Inspiration" skillId="1405" skillLvl="1" getLevel="52" learnedByNpc="true">
  18.                         <item id="8618" count="1" />
  19.                 </skill>
  20.                 <skill skillName="Divine Inspiration" skillId="1405" skillLvl="2" getLevel="61" learnedByNpc="true">
  21.                         <item id="8619" count="1" />
  22.                 </skill>
复制代码
结果中,首行显示的是字段名,无需输出,我手填写就行。所有内容我自己粘到一个res.txt中,输出到sour.csv中即可。处理后的内容如下:

  1. ClassId        skillname        skillId        skillLvl        getLevel        levelUpSp        Item ID        item_count
  2. 0        luck        194        1        1                       
  3. 0        Expertise D        239        1        20                       
  4. 116        Wisdom        328        1        76        8300000               
  5. 116        Health        329        1        76        8300000               
  6. 116        Sigil Mastery        935        1        76        8300000               
  7. 24        Divine Inspiration        1405        1        52                8618        1
  8. 24        Divine Inspiration        1405        2        61                8619        1
复制代码
谢谢各位大佬。
发表于 2024-2-28 19:25:43 | 显示全部楼层
  1.                 <skill skillName="Lucky" skillId="194" skillLvl="1" getLevel="1" autoGet="true" />
  2.                 <skill skillName="Wisdom" skillId="328" skillLvl="1" getLevel="76" levelUpSp="8300000" learnedByNpc="true" />
  3.                 <skill skillName="Divine Inspiration" skillId="1405" skillLvl="1" getLevel="52" learnedByNpc="true">
复制代码


是否skillName 行只有这三种组合形式?
执行以下代码观察下
  1. find "skill skillName=" *.xml >1.txt
复制代码
发表于 2024-2-28 21:32:05 | 显示全部楼层
  1. rem 另存为 ANSI 编码 的 bat
  2. ' & cls & CScript.exe /nologo /e:vbscript "%~f0" >sour.csv & pause & exit

  3. Option Explicit
  4. Dim oFSO, oDOMDocument, s

  5. Set oFSO = CreateObject("Scripting.FileSystemObject")
  6. Set oDOMDocument = CreateObject("Msxml2.DOMDocument.6.0")
  7. wsh.Echo "ClassId        skillname        skillId        skillLvl        getLevel        levelUpSp        Item ID        item_count"
  8. For Each s In oFSO.GetFolder(oFSO.GetAbsolutePathName(".")).Files
  9.     If LCase(oFSO.GetExtensionName(s)) = "xml" Then Call k(s.Path)
  10. Next

  11. Sub k(ByVal s)
  12.     Dim i, j, m, t
  13.     oDOMDocument.Load s
  14.     For Each i In oDOMDocument.SelectNodes("//skillTree")
  15.         For Each j In i.SelectNodes("skill")
  16.             t = i.getAttribute("classId") & vbTab
  17.             t = t & j.getAttribute("skillName") & vbTab _
  18.                   & j.getAttribute("skillId")   & vbTab _
  19.                   & j.getAttribute("skillLvl")  & vbTab _
  20.                   & j.getAttribute("getLevel")  & vbTab _
  21.                   & j.getAttribute("levelUpSp") & vbTab
  22.             For Each m In j.SelectNodes("item")
  23.                 t = t & m.getAttribute("id")    & vbTab _
  24.                       & m.getAttribute("count") & vbTab
  25.             Next
  26.             wsh.Echo Left(t, Len(t) - 1)
  27.         Next
  28.     Next
  29. End Sub
复制代码
发表于 2024-2-28 22:50:31 | 显示全部楼层
根据要求,只针对同级位置的res.txt文件处理,结果不要求显示标题行,并导出为sour.csv的表格中。
  1. @echo off&setlocal enabledelayedexpansion
  2. for /f tokens^=1-12^delims^=^=^" %%0 in ('findstr "=" "res.txt"') do (
  3.     if "%%2" == " classId" (set v1=%%3
  4.     ) else (
  5.         if "%%8" == " autoGet"  (echo.!v1!, %%1, %%3, %%5, %%7
  6.         ) else (
  7.             if "%%8" == " learnedByNpc"  (set v2=!v1!, %%1, %%3, %%5, %%7
  8.             ) else (
  9.                 if "%%2" == " count" (echo !v2!, %%1, %%3
  10.                 ) else (
  11.                     echo.!v1!, %%1, %%3, %%5, %%7, %%9
  12.                         )
  13.                     )
  14.                 )   
  15.             )
  16. )>>sour.csv
复制代码
 楼主| 发表于 2024-2-28 23:37:48 | 显示全部楼层
czjt1234 发表于 2024-2-28 21:32



你们实在太厉害了。谢谢,可以用,太效率了。
发表于 2024-2-29 09:57:20 | 显示全部楼层

楼主的几轮帖子把纯P的for/f切割器开出刃来了...

  1. @echo off &setlocal enabledelayedexpansion
  2. (for /f tokens^=1-10^ delims^=^        ^=^<^" %%a in (' findstr "=" "1.xml" ') do (
  3.         if /i "%%a"=="skillTree type" (set "v1=%%d")
  4.         if /i "%%a"=="skill skillName" (
  5.                 if defined v (echo,)
  6.                 set "v=!v1!        %%b        %%d        %%f        %%h"
  7.                 if /i "%%j" neq "true" (set "v=!v!        %%j")
  8.                 set/p="!v!"<nul)
  9.         if /i "%%a"=="item id" (echo,        %%b        %%d&set "v=")
  10. ))>"sour.csv"
  11. endlocal&exit/b
复制代码
发表于 2024-2-29 10:44:16 | 显示全部楼层

再换一种纯P老刀的切法,顺便复习一遍 if 句式中如何比较双引号"的方法...

  1. @echo off &setlocal enabledelayedexpansion
  2. (for /f "tokens=1* delims=        < " %%a in (' findstr "=" "1.xml" ') do (
  3.         if /i "%%~a"=="skillTree" for /f tokens^=1-4^ delims^=^" %%1 in ("%%~b") do (set "v1=%%4")
  4.         if /i "%%~a"=="skill" (
  5.                 if defined v (echo,)
  6.                 set "v=!v1!" & for %%i in (%%~b) do (
  7.                         set i=%%i &set "c=!i:~,1!"
  8.                         if ^!c!==^" if /i "!i:~1,4!" neq "true" set "v=!v!        !i:~1,-2!")
  9.                 set/p="!v!"<nul
  10.         )
  11.         if /i "%%~a"=="item" for /f tokens^=1-4^ delims^=^" %%1 in ("%%~b") do (echo,        %%2        %%4&set "v=")
  12. ))>"sour.csv"
  13. endlocal&exit/b
复制代码
发表于 2024-2-29 15:25:46 | 显示全部楼层
本帖最后由 qixiaobin0715 于 2024-2-29 16:36 编辑

先使用for /f中的切分功能排除干扰字符,后面直指主题,即直接找出各字段对应的内容,感觉这样应当更准确些,防止出现某些位置异常而产生匹配错误的情况:
  1. @echo off
  2. set /a #ClassId=#skillname=#skillId=#skillLvl=#getLevel=#levelUpSp=#ID=#count=0
  3. setlocal enabledelayedexpansion
  4. for /f "delims=<>        " %%x in (1.log) do (
  5.     for /f "tokens=1*" %%i in ("%%x") do (
  6.         for %%a in (%%j) do (
  7.             if defined x (
  8.                 set !x!=%%~a
  9.                 set x=
  10.             ) else if defined #%%a (
  11.                 set x=%%a
  12.             )
  13.             if /i "%%a"=="/" (
  14.                 echo,!ClassId!        !skillname!        !skillId!        !skillLvl!        !getLevel!        !levelUpSp!        !ID!        !count!
  15.                 for %%y in (skillname skillId skillLvl getLevel levelUpSp ID count) do set %%y=
  16.             )
  17.         )
  18.     )
  19. )
  20. pause
复制代码
开始上面代码好像有些问题,现已修改。
发表于 2024-2-29 16:14:01 | 显示全部楼层

用jscript在纯P壳里跑一遍,处理大数据应会有明显效率差别
以下代码存为test.bat运行,结果生成与源文件 1.xml (一楼示例样本)对应的 sour.csv

  1. @set @v=1 /* @echo off & type "1.xml"|cscript /e:jscript "%~f0">"sour.csv" &exit/b
  2. */
  3. var lines = WSH.stdin.readall().split('\n');
  4. var v1, v, tk, tk0, ltk, vLines = [];
  5. for (var n=0,l=lines.length; n<l; n++) {
  6.         if (lines[n].indexOf('=') == -1) continue;
  7.         tk = lines[n].split(/[\t=<]+/); ltk = tk.length; tk0 = tk[0].toLowerCase();
  8.         if (tk0 == 'skilltree type') v1 = tk[2].split(/"+/)[0];
  9.         else if (tk0 == 'skill skillname') {
  10.                 v = v1;
  11.                 for (var k=1; k<ltk; k++)
  12.                         if (tk[k].slice(0,1) == '"' && tk[k].slice(1,5).toLowerCase() != 'true')
  13.                                 v += '\t'+tk[k].split(/"+/)[0];
  14.                 vLines.push(v);
  15.         } else if (tk0 == 'item id') {
  16.                 v += '\t'+tk[1].split(/"+/)[0]+'\t'+tk[2].split(/"+/)[0]; vLines.pop(); vLines.push(v);
  17.         }
  18. }
  19. WSH.echo(vLines.join('\n'));
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-3-18 04:06 , Processed in 0.020818 second(s), 8 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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