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

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

[复制链接]
发表于 2023-12-14 09:58:53 | 显示全部楼层 |阅读模式
本帖最后由 zhengwei007 于 2023-12-14 10:45 编辑

我想从100多个文档里面,发现有Soul Crystal字符时,截取下面一行的ID 4645,和最后一行的4682,单独存放在csv文件里。
文档中是以<item>开头,</item>结尾的,谢谢大家。
由于不能上传附件,我粘点里面内容吧。
  1.         <item>
  2.                 <!-- Stormbringer -->
  3.                 <ingredient count="1" id="72" />
  4.                 <!-- Red Soul Crystal - Stage 5 -->
  5.                 <ingredient count="1" id="4634" />
  6.                 <!-- Gemstone C -->
  7.                 <ingredient count="97" id="2131" />
  8.                 <!-- Adena -->
  9.                 <ingredient count="291000" id="57" />
  10.                 <!-- Stormbringer - Critical Anger -->
  11.                 <production count="1" id="4681" />
  12.         </item>
  13.         <item>
  14.                 <!-- Stormbringer -->
  15.                 <ingredient count="1" id="72" />
  16.                 <!-- Green Soul Crystal - Stage 5 -->
  17.                 <ingredient count="1" id="4645" />
  18.                 <!-- Gemstone C -->
  19.                 <ingredient count="97" id="2131" />
  20.                 <!-- Adena -->
  21.                 <ingredient count="291000" id="57" />
  22.                 <!-- Stormbringer - Focus -->
  23.                 <production count="1" id="4682" />
  24.         </item>
复制代码
从这里提取4634和4681即可,每个文件里可能有多个这样的内容结构。
最终csv就是这样:
4634,4681
4645,4682

链接:https://pan.baidu.com/s/13ecRnqY4tPRaoFcVBEBLTg
提取码:xlit
这里存放了几个真实的文本文件的下载地址。
发表于 2023-12-14 10:05:33 | 显示全部楼层
回复 1# zhengwei007


    请选择其中3个文件打包压缩上传到网盘我试试
 楼主| 发表于 2023-12-14 10:30:45 | 显示全部楼层
链接:https://pan.baidu.com/s/13ecRnqY4tPRaoFcVBEBLTg
提取码:xlit
--来自百度网盘超级会员V9的分享

谢谢管理。
发表于 2023-12-14 10:37:23 | 显示全部楼层
回复 3# zhengwei007


    请编辑一下顶楼的帖子,把下载链接放进去,方便他人看到。
 楼主| 发表于 2023-12-14 10:46:08 | 显示全部楼层
回复  zhengwei007


    请编辑一下顶楼的帖子,把下载链接放进去,方便他人看到。
Batcher 发表于 2023-12-14 10:37



   
好的,已经编辑完成。
发表于 2023-12-14 12:52:49 | 显示全部楼层
用的busybox的sh,这东西可以打包成exe,写的丑了点
  1. for f in *.xml; do awk -v RS='</item>' -F '\n' '/Soul Crystal/{for(i=1;i<=NF;i++){if($i~/Soul Crystal/){gsub(".*id="|".*","",$(i+1));gsub(".*id="|".*","",$(NF-1));print $(i+1)","$(NF-1)}}}' "$f" > "$f.csv"; done
复制代码
 楼主| 发表于 2023-12-14 13:24:03 | 显示全部楼层
用的busybox的sh,这东西可以打包成exe,写的丑了点
wanghan519 发表于 2023-12-14 12:52



可以做成批处理文件吗?.bat后缀,我可以直接执行的那种。我这没有linux,谢谢!
发表于 2023-12-14 14:07:09 | 显示全部楼层
回复 7# zhengwei007


    呃,bat处理引号我是真不会。。。
可以下个busybox-w32执行,也就0.5M,提供sh环境包括awk,且可以把脚本编译成exe,很方便的小工具
 楼主| 发表于 2023-12-14 14:55:45 | 显示全部楼层
回复  zhengwei007


    呃,bat处理引号我是真不会。。。
可以下个busybox-w32执行,也就0.5M,提供 ...
wanghan519 发表于 2023-12-14 14:07



你好,我试过了,可能有一点没说清楚,是所有数据全部汇总到一个csv下,不是单独的csv文件。随便起个名字,data.csv就行。
发表于 2023-12-14 15:08:34 | 显示全部楼层

测试文件名假设为 test.xml
获取结果文件名为 test.csv
如下代码存为批处理脚本文件(test.cmd 或 test.bat)
楼主提供的样本已测试通过。

  1. @echo off &setlocal enabledelayedexpansion
  2. findstr /inc:"Soul Crystal" /inc:"</item>" "test.xml" 2>nul>tmp.0
  3. (for /f "tokens=1 delims=:" %%k in (tmp.0) do (
  4.         if not defined v1 (call :getV "test.xml" %%k v1) else (
  5.                 set/a "n=%%k-2"
  6.                 (call :getV "test.xml" !n! v2)
  7.                 echo,!v1!,!v2!
  8.                 set "v1="
  9.         )
  10. ))>"test.csv"
  11. del /q tmp.0
  12. endlocal &pause &exit/b
  13. :getV //%1=文件名 %2=行号 %3=返回值变量名
  14.         for /f "usebackq skip=%~2 delims=" %%s in ("%~1") do (
  15.                 for /f tokens^=1-4^delims^=^" %%1 in ("%%~s") do (set "%~3=%%4")
  16.                 exit/b
  17.         ) & exit/b
复制代码
 楼主| 发表于 2023-12-14 15:37:17 | 显示全部楼层
谢谢6楼和10楼的兄弟,问题已经全部解决。
发表于 2023-12-14 16:45:31 | 显示全部楼层
  1. @echo off
  2. cd /d "%~dp0"
  3. (for %%i in (*.xml) do (
  4.         setlocal
  5.         for /f "useback delims=" %%a in ("%%i") do (
  6.                 set str=%%a
  7.                 setlocal enabledelayedexpansion
  8.                 set "str1=!str:Soul Crystal=!"
  9.                 set "str2=!str:        </item>=!"
  10.                 if "!str!" neq "!str1!" (
  11.                         endlocal
  12.                         set m=1
  13.                 ) else if defined m (
  14.                         endlocal
  15.                         for /f tokens^=4delims^=^" %%x in ("%%a") do (
  16.                                 set n=%%x
  17.                         )
  18.                         set m=
  19.                 ) else if "!str!" neq "!str2!" (
  20.                         endlocal
  21.                         if defined n (
  22.                                 setlocal enabledelayedexpansion
  23.                                 for /f tokens^=4delims^=^" %%x in ("!_str!") do (
  24.                                         echo !n!,%%x
  25.                                 )
  26.                                 endlocal
  27.                                 set n=
  28.                         )
  29.                 ) else (
  30.                         endlocal
  31.                 )
  32.                 set _str=%%a
  33.         )
  34.         endlocal
  35. ))>data.csv
  36. pause

复制代码
发表于 2023-12-14 19:17:03 | 显示全部楼层
回复 1# zhengwei007

假设所有xml文件均在同1个文件夹下,用第3方工具gaw( http://bcn.bathome.net/tool/5.1.0/gawk.exe ),在命令行方式下,其实现方法如下:

  1. awk -v"OFS=," "/^\t+<item>$/,/^\t+<\/item>$/{if(/Soul Crystal/)exist_id=1;if(/^\t+<ingredient count="1" id="[0-9]+" \/>$/)if(exist_id)A=gensub(/^\t+<ingredient count="1" id="([0-9]+)" \/>$/,"\\1","g",$0);if(/^\t+<production count="1" id="[0-9]+" \/>$/)if(exist_id)print A,gensub(/^\t+<production count="1" id="([0-9]+)" \/>$/,"\\1","g",$0);if(/^\t+<\/item>$/)exist_id=0}" *.xml>out.csv
复制代码
发表于 2023-12-14 20:39:39 | 显示全部楼层
本帖最后由 WHY 于 2023-12-17 23:02 编辑
  1. @if(0)==(0) echo off
  2. dir /b *.xml | cscript -nologo -e:jscript "%~f0" > result.csv
  3. pause & exit
  4. @end

  5. var fso = new ActiveXObject('Scripting.FileSystemObject');

  6. while(!WSH.StdIn.AtEndOfStream) {
  7.     var f = WSH.StdIn.ReadLine();
  8.     var s = fso.OpenTextfile(f, 1).ReadAll();
  9.     var m = s.match(/<item>(?:(?!<\/?item>)[\s\S])+<\/item>/g);
  10.     for(var i=0; i<m.length; i++) {
  11.         var m1 = m[i].match(/\bSoul Crystal\b.+\n(?:(?!\bid=).)+\bid="([^"]+)"/);
  12.         var m2 = m[i].match(/\bproduction\b(?:(?!\bid=).)+\bid="([^"]+)"/);
  13.         if(m1 && m2) WSH.Echo(m1[1] + ',' + m2[1]);
  14.     }
  15. }
复制代码
  1. @if(0)==(0) echo off
  2. dir /b *.xml | cscript -nologo -e:jscript "%~f0" > result.csv
  3. pause & exit
  4. @end

  5. var xml = new ActiveXObject('Microsoft.XMLDOM');
  6. var reg = /\bSoul Crystal\b/;

  7. while(!WSH.StdIn.AtEndOfStream) {
  8.     var f = WSH.StdIn.ReadLine();
  9.     getXmlData(f);
  10. }

  11. function getXmlData(fileName) {
  12.     xml.load(fileName);
  13.     var nodes = xml.selectNodes('//item');
  14.     for(var i=0; i<nodes.length; i++) {
  15.         var s2 = nodes[i].lastChild.getAttribute('id');
  16.         var childs = nodes[i].childNodes;
  17.         for(var j=0; j<childs.length; j++) {
  18.             if(childs[j].nodeName == '#comment' && reg.test(childs[j].text)) {
  19.                 var s1 = childs[j+1].getAttribute('id');
  20.                 WSH.Echo(s1 + ',' + s2);
  21.                 break;
  22.             }
  23.         }
  24.     }
  25. }
复制代码
发表于 2023-12-15 02:00:25 | 显示全部楼层
这样行不?

  1. @echo off&chcp 936
  2. echo 进行中,请耐心等待
  3. set "outfile=___output.csv"

  4. cd.>"%outfile%"
  5. for %%b in ("*.xml") do (
  6. setlocal
  7. echo,file,%%~b>>%outfile%
  8. (for /f "skip=1 delims=" %%c in ('findstr /n .* "%%~b"') do (
  9. set line1=
  10. set /p line1=
  11. set line2=%%c

  12. if not defined item (
  13. setlocal enabledelayedexpansion
  14. if "!line1:<item>=!" neq "!line1!" (
  15. for %%- in (1) do endlocal&set item=%%-) else endlocal
  16. ) else (

  17. setlocal enabledelayedexpansion
  18. if "!line1:Soul Crystal=!" neq "!line1!" (
  19. set line3=!line2:* =!&set line3=!line3:~0,-2!
  20. 2>nul set /a !line3:id=,id!
  21. for %%- in ("!id!") do endlocal&set o=%%~-&set match=1
  22. if "!p!" == "!q!" endlocal
  23. ) else endlocal

  24. if defined match (
  25. setlocal enabledelayedexpansion
  26. if "!line2:</item>=!" neq "!line2!" (
  27. set line3=!line1:* =!&set line3=!line3:~0,-2!
  28. 2>nul set /a !line3:id=,id!
  29. echo,!o!,!id!
  30. endlocal&set o=&set match=&set item=
  31. ) else endlocal
  32. )

  33. )
  34. ))<"%%~b">>"%outfile%"
  35. endlocal
  36. )
  37. echo,&echo 完成&pause
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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