Board logo

标题: [文本处理] 【已解决】求助批处理从一堆文本文件中提取关键词写到csv中 [打印本页]

作者: zhengwei007    时间: 2024-3-7 13:44     标题: 【已解决】求助批处理从一堆文本文件中提取关键词写到csv中

本帖最后由 zhengwei007 于 2024-3-8 09:10 编辑

我有几百个这样的xml文档,文档中是以<skill id=****>开头,</skill>结尾的,想通过批处理将里面内容整理出来,其中一个XML内容如下:
  1. <skill id="2658" levels="1" name="Dual Dagger Mastery">
  2. <!-- Confirmed CT2.5 -->
  3. <set name="hitTime" val="1500" />
  4. <set name="isMagic" val="2" /> <!-- Static Skill -->
  5. <set name="itemConsumeCount" val="1" />
  6. <set name="itemConsumeId" val="14210" />
  7. <set name="magicLvl" val="81" />
  8. <set name="operateType" val="A1" />
  9. <set name="targetType" val="SELF" />
  10. <cond msgId="113" addName="1">
  11. <and>
  12. <not>
  13. <player active_skill_id="923" />
  14. </not>
  15. <player class_id_restriction="93, 101, 108, 117" />
  16. <player level="81" />
  17. </and>
  18. </cond>
  19. <for>
  20. <effect name="SetSkill">
  21. <param skillId="923" skillLvl="1" />
  22. </effect>
  23. </for>
  24. </skill>
  25. <skill id="2659" levels="1" name="Seven Arrow">
  26. <!-- Confirmed CT2.5 -->
  27. <set name="hitTime" val="1500" />
  28. <set name="isMagic" val="2" /> <!-- Static Skill -->
  29. <set name="itemConsumeCount" val="1" />
  30. <set name="itemConsumeId" val="14211" />
  31. <set name="magicLvl" val="1" />
  32. <set name="operateType" val="A1" />
  33. <set name="targetType" val="SELF" />
  34. <cond msgId="113" addName="1">
  35. <and>
  36. <not>
  37. <player active_skill_id="924" />
  38. </not>
  39. <player class_id_restriction="92, 102, 109" />
  40. <player level="81" />
  41. </and>
  42. </cond>
  43. <for>
  44. <effect name="SetSkill">
  45. <param skillId="924" skillLvl="1" />
  46. </effect>
  47. </for>
  48. </skill>
复制代码
下面结果的标题是我单加的,批处理跑完直接从第2行开始显示。如果缺少的字段,请留空值。
最终结果如下:
skill ID        levels        name        hitTime        isMagic        itemConsumeCount        itemConsumeId        magicLvl        operateType        targetType
2658        1        Dual Dagger Mastery        1500        2        1        14210        81        A1        SELF
2659        1        Seven Arrow        1500        2        1        14211        1        A1        SELF
作者: aloha20200628    时间: 2024-3-7 15:25

回复 1# zhengwei007

程式化 克隆...
  1. @echo off &setlocal enabledelayedexpansion
  2. chcp 65001>nul&cls
  3. (for /f tokens^=1-6^ delims^=^ ^=^<^" %%1 in (' findstr "=" "1.xml" ') do (
  4. if /i "%%1"=="skill id" ((if defined v echo,!v!)&set "v=%%2 %%4 %%6")
  5. if /i "%%1"=="set name" (set "v=!v! %%4")
  6. ))>"sour.csv"
  7. if defined v (echo,!v!)>>"sour.csv"
  8. endlocal&exit/b
复制代码

作者: zhengwei007    时间: 2024-3-7 16:42

回复  zhengwei007

程式化 克隆...
aloha20200628 发表于 2024-3-7 15:25


大佬,我这是几百个文件,要从这几百个文件中找,不单单是1.xml,只是把结果汇总到sour.csv就行。
作者: aloha20200628    时间: 2024-3-7 17:49

回复 3# zhengwei007
  1. @echo off &setlocal enabledelayedexpansion
  2. chcp 65001>nul&cls
  3. (for /f "delims=" %%F in ('dir/b/s/a-d *.xml') do (
  4. for /f tokens^=1-6^ delims^=^ ^=^<^" %%1 in (' findstr "=" "%%~F" ') do (
  5. if /i "%%1"=="skill id" ((if defined v echo,!v!)&set "v=%%2 %%4 %%6")
  6. if /i "%%1"=="set name" (set "v=!v! %%4")
  7. )
  8. if defined v (echo,!v!&set "v=")
  9. ))>"sour.csv"
  10. endlocal&exit/b
复制代码

作者: hfxiang    时间: 2024-3-7 19:29

回复 1# zhengwei007

一般情况下csv文件的分隔符为逗号(,),故借用gawk(http://bcn.bathome.net/tool/4.1.0/gawk.exe)来处置后本例输出结果分隔符设置为逗号(,),同时假定所有xml文件在同1个文件夹中,实现脚本(亦可命令行直接执行)如下:
  1. gawk -v"FS=\042" "BEGIN{str=\"skill id,levels,name,hitTime,isMagic,itemConsumeCount,itemConsumeId,magicLvl,operateType,targetType\";split(str,s,/,/);print str}/<skill id=/,/<\/skill>/{if(/<skill id=/){b=$2;a[\"levels\"]=$4;a[\"name\"]=$6};if(/<set name=/){a[$2]=$4};if(/<\/skill>/){for(i=2;i<=10;i++){b=b\",\"a[s[i]]}print b;b=\"\";delete a}}" *.xml>out.csv
复制代码

作者: ppll2030    时间: 2024-3-7 19:41

本帖最后由 ppll2030 于 2024-3-7 19:54 编辑

回复 1# zhengwei007


    对目录下(含子目录)所有.xml进行处理,生成结果提取文件res.csv
  1. @echo off &setlocal enabledelayedexpansion
  2. for /f "delims=" %%f in ('dir /b /s /a-d "*.xml"') do (
  3. for /f tokens^=1-7^delims^=^<^" %%1 in ('type "%%~f"') do (
  4. if "%%~2" == "skill id=" set "v=%%3, %%7"
  5. if "%%~2" == "set name=" set "v=!v!, %%5"
  6. if "%%~2" == "/skill>" echo, !v!
  7. )
  8. )>>res.csv
  9. pause
复制代码

作者: aloha20200628    时间: 2024-3-7 20:31

本帖最后由 aloha20200628 于 2024-3-7 20:33 编辑


为进一步提高for/f逐行处理的效率,可用 skill id 和 set name 过滤其余冗余行,至少约占示例文件的1/2总行数,放大至几百个文件,其效率增益还是可观的...
订正4楼代码如下
  1. @echo off &setlocal enabledelayedexpansion
  2. chcp 65001>nul&cls
  3. (for /f "delims=" %%F in ('dir/b/s/a-d *.xml') do (
  4. for /f tokens^=1-6^ delims^=^ ^=^<^" %%1 in (' findstr /ic:"skill id=" /ic:"set name=" "%%~F" ') do (
  5. if /i "%%1"=="skill id" ((if defined v echo,!v!)&set "v=%%2 %%4 %%6")
  6. if /i "%%1"=="set name" (set "v=!v! %%4")
  7. )
  8. if defined v (echo,!v!&set "v=")
  9. ))>"sour.csv"
  10. endlocal&exit/b
复制代码

作者: zhengwei007    时间: 2024-3-8 09:10

谢谢楼上几位大佬,问题解决了。




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