[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

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

本帖最后由 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
复制代码
谢谢各位大佬。

  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
复制代码
bat小白,请多指教!谢谢!

TOP

  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
复制代码

QQ 20147578

TOP

根据要求,只针对同级位置的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
复制代码

TOP

czjt1234 发表于 2024-2-28 21:32



你们实在太厉害了。谢谢,可以用,太效率了。

TOP


楼主的几轮帖子把纯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
复制代码

TOP


再换一种纯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
复制代码

TOP

本帖最后由 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
复制代码
开始上面代码好像有些问题,现已修改。

TOP


用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'));
复制代码

TOP

返回列表