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

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

[复制链接]
发表于 2024-3-7 13:44:54 | 显示全部楼层 |阅读模式
本帖最后由 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

评分

参与人数 1PB +2 收起 理由
Batcher + 2 感谢给帖子标题标注[已解决]字样

查看全部评分

发表于 2024-3-7 15:25:50 | 显示全部楼层
回复 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
复制代码
 楼主| 发表于 2024-3-7 16:42:45 | 显示全部楼层
回复  zhengwei007

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


大佬,我这是几百个文件,要从这几百个文件中找,不单单是1.xml,只是把结果汇总到sour.csv就行。
发表于 2024-3-7 17:49:36 | 显示全部楼层
回复 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
复制代码
发表于 2024-3-7 19:29:25 | 显示全部楼层
回复 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
复制代码

评分

参与人数 1技术 +1 收起 理由
Batcher + 1 乐于助人

查看全部评分

发表于 2024-3-7 19:41:49 | 显示全部楼层
本帖最后由 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
复制代码

评分

参与人数 1技术 +1 收起 理由
Batcher + 1 乐于助人

查看全部评分

发表于 2024-3-7 20:31:05 | 显示全部楼层
本帖最后由 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
复制代码

评分

参与人数 1技术 +1 收起 理由
Batcher + 1 乐于助人

查看全部评分

 楼主| 发表于 2024-3-8 09:10:33 | 显示全部楼层
谢谢楼上几位大佬,问题解决了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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