标题: [文本处理] 【已解决】求助批处理从一堆文本文件中提取关键词写到csv中 [打印本页]
作者: zhengwei007 时间: 2024-3-7 13:44 标题: 【已解决】求助批处理从一堆文本文件中提取关键词写到csv中
本帖最后由 zhengwei007 于 2024-3-8 09:10 编辑
我有几百个这样的xml文档,文档中是以<skill id=****>开头,</skill>结尾的,想通过批处理将里面内容整理出来,其中一个XML内容如下:- <skill id="2658" levels="1" name="Dual Dagger Mastery">
- <!-- Confirmed CT2.5 -->
- <set name="hitTime" val="1500" />
- <set name="isMagic" val="2" /> <!-- Static Skill -->
- <set name="itemConsumeCount" val="1" />
- <set name="itemConsumeId" val="14210" />
- <set name="magicLvl" val="81" />
- <set name="operateType" val="A1" />
- <set name="targetType" val="SELF" />
- <cond msgId="113" addName="1">
- <and>
- <not>
- <player active_skill_id="923" />
- </not>
- <player class_id_restriction="93, 101, 108, 117" />
- <player level="81" />
- </and>
- </cond>
- <for>
- <effect name="SetSkill">
- <param skillId="923" skillLvl="1" />
- </effect>
- </for>
- </skill>
- <skill id="2659" levels="1" name="Seven Arrow">
- <!-- Confirmed CT2.5 -->
- <set name="hitTime" val="1500" />
- <set name="isMagic" val="2" /> <!-- Static Skill -->
- <set name="itemConsumeCount" val="1" />
- <set name="itemConsumeId" val="14211" />
- <set name="magicLvl" val="1" />
- <set name="operateType" val="A1" />
- <set name="targetType" val="SELF" />
- <cond msgId="113" addName="1">
- <and>
- <not>
- <player active_skill_id="924" />
- </not>
- <player class_id_restriction="92, 102, 109" />
- <player level="81" />
- </and>
- </cond>
- <for>
- <effect name="SetSkill">
- <param skillId="924" skillLvl="1" />
- </effect>
- </for>
- </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
程式化 克隆...- @echo off &setlocal enabledelayedexpansion
- chcp 65001>nul&cls
- (for /f tokens^=1-6^ delims^=^ ^=^<^" %%1 in (' findstr "=" "1.xml" ') do (
- if /i "%%1"=="skill id" ((if defined v echo,!v!)&set "v=%%2 %%4 %%6")
- if /i "%%1"=="set name" (set "v=!v! %%4")
- ))>"sour.csv"
- if defined v (echo,!v!)>>"sour.csv"
- 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
- @echo off &setlocal enabledelayedexpansion
- chcp 65001>nul&cls
- (for /f "delims=" %%F in ('dir/b/s/a-d *.xml') do (
- for /f tokens^=1-6^ delims^=^ ^=^<^" %%1 in (' findstr "=" "%%~F" ') do (
- if /i "%%1"=="skill id" ((if defined v echo,!v!)&set "v=%%2 %%4 %%6")
- if /i "%%1"=="set name" (set "v=!v! %%4")
- )
- if defined v (echo,!v!&set "v=")
- ))>"sour.csv"
- 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个文件夹中,实现脚本(亦可命令行直接执行)如下:- 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- @echo off &setlocal enabledelayedexpansion
- for /f "delims=" %%f in ('dir /b /s /a-d "*.xml"') do (
- for /f tokens^=1-7^delims^=^<^" %%1 in ('type "%%~f"') do (
- if "%%~2" == "skill id=" set "v=%%3, %%7"
- if "%%~2" == "set name=" set "v=!v!, %%5"
- if "%%~2" == "/skill>" echo, !v!
- )
- )>>res.csv
- pause
复制代码
作者: aloha20200628 时间: 2024-3-7 20:31
本帖最后由 aloha20200628 于 2024-3-7 20:33 编辑
为进一步提高for/f逐行处理的效率,可用 skill id 和 set name 过滤其余冗余行,至少约占示例文件的1/2总行数,放大至几百个文件,其效率增益还是可观的...
订正4楼代码如下- @echo off &setlocal enabledelayedexpansion
- chcp 65001>nul&cls
- (for /f "delims=" %%F in ('dir/b/s/a-d *.xml') do (
- for /f tokens^=1-6^ delims^=^ ^=^<^" %%1 in (' findstr /ic:"skill id=" /ic:"set name=" "%%~F" ') do (
- if /i "%%1"=="skill id" ((if defined v echo,!v!)&set "v=%%2 %%4 %%6")
- if /i "%%1"=="set name" (set "v=!v! %%4")
- )
- if defined v (echo,!v!&set "v=")
- ))>"sour.csv"
- endlocal&exit/b
复制代码
作者: zhengwei007 时间: 2024-3-8 09:10
谢谢楼上几位大佬,问题解决了。
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |