返回列表 发帖

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

本帖最后由 zhengwei007 于 2023-12-14 10:45 编辑

我想从100多个文档里面,发现有Soul Crystal字符时,截取下面一行的ID 4645,和最后一行的4682,单独存放在csv文件里。
文档中是以<item>开头,</item>结尾的,谢谢大家。
由于不能上传附件,我粘点里面内容吧。
<item>
<!-- Stormbringer -->
<ingredient count="1" id="72" />
<!-- Red Soul Crystal - Stage 5 -->
<ingredient count="1" id="4634" />
<!-- Gemstone C -->
<ingredient count="97" id="2131" />
<!-- Adena -->
<ingredient count="291000" id="57" />
<!-- Stormbringer - Critical Anger -->
<production count="1" id="4681" />
</item>
<item>
<!-- Stormbringer -->
<ingredient count="1" id="72" />
<!-- Green Soul Crystal - Stage 5 -->
<ingredient count="1" id="4645" />
<!-- Gemstone C -->
<ingredient count="97" id="2131" />
<!-- Adena -->
<ingredient count="291000" id="57" />
<!-- Stormbringer - Focus -->
<production count="1" id="4682" />
</item>COPY
从这里提取4634和4681即可,每个文件里可能有多个这样的内容结构。
最终csv就是这样:
4634,4681
4645,4682

链接:https://pan.baidu.com/s/13ecRnqY4tPRaoFcVBEBLTg
提取码:xlit
这里存放了几个真实的文本文件的下载地址。

回复 1# zhengwei007


    请选择其中3个文件打包压缩上传到网盘我试试
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

链接:https://pan.baidu.com/s/13ecRnqY4tPRaoFcVBEBLTg
提取码:xlit
--来自百度网盘超级会员V9的分享

谢谢管理。

TOP

回复 3# zhengwei007


    请编辑一下顶楼的帖子,把下载链接放进去,方便他人看到。
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

回复  zhengwei007


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



   
好的,已经编辑完成。

TOP

用的busybox的sh,这东西可以打包成exe,写的丑了点
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"; doneCOPY

TOP

用的busybox的sh,这东西可以打包成exe,写的丑了点
wanghan519 发表于 2023-12-14 12:52



可以做成批处理文件吗?.bat后缀,我可以直接执行的那种。我这没有linux,谢谢!

TOP

回复 7# zhengwei007


    呃,bat处理引号我是真不会。。。
可以下个busybox-w32执行,也就0.5M,提供sh环境包括awk,且可以把脚本编译成exe,很方便的小工具

TOP

回复  zhengwei007


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



你好,我试过了,可能有一点没说清楚,是所有数据全部汇总到一个csv下,不是单独的csv文件。随便起个名字,data.csv就行。

TOP


测试文件名假设为 test.xml
获取结果文件名为 test.csv
如下代码存为批处理脚本文件(test.cmd 或 test.bat)
楼主提供的样本已测试通过。
@echo off &setlocal enabledelayedexpansion
findstr /inc:"Soul Crystal" /inc:"</item>" "test.xml" 2>nul>tmp.0
(for /f "tokens=1 delims=:" %%k in (tmp.0) do (
if not defined v1 (call :getV "test.xml" %%k v1) else (
set/a "n=%%k-2"
(call :getV "test.xml" !n! v2)
echo,!v1!,!v2!
set "v1="
)
))>"test.csv"
del /q tmp.0
endlocal &pause &exit/b
:getV //%1=文件名 %2=行号 %3=返回值变量名
for /f "usebackq skip=%~2 delims=" %%s in ("%~1") do (
for /f tokens^=1-4^delims^=^" %%1 in ("%%~s") do (set "%~3=%%4")
exit/b
) & exit/bCOPY

TOP

谢谢6楼和10楼的兄弟,问题已经全部解决。

TOP

@echo off
cd /d "%~dp0"
(for %%i in (*.xml) do (
setlocal
for /f "useback delims=" %%a in ("%%i") do (
set str=%%a
setlocal enabledelayedexpansion
set "str1=!str:Soul Crystal=!"
set "str2=!str: </item>=!"
if "!str!" neq "!str1!" (
endlocal
set m=1
) else if defined m (
endlocal
for /f tokens^=4delims^=^" %%x in ("%%a") do (
set n=%%x
)
set m=
) else if "!str!" neq "!str2!" (
endlocal
if defined n (
setlocal enabledelayedexpansion
for /f tokens^=4delims^=^" %%x in ("!_str!") do (
echo !n!,%%x
)
endlocal
set n=
)
) else (
endlocal
)
set _str=%%a
)
endlocal
))>data.csv
pauseCOPY
bat小白,请多指教!谢谢!

TOP

回复 1# zhengwei007

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

TOP

本帖最后由 WHY 于 2023-12-17 23:02 编辑
@if(0)==(0) echo off
dir /b *.xml | cscript -nologo -e:jscript "%~f0" > result.csv
pause & exit
@end
var fso = new ActiveXObject('Scripting.FileSystemObject');
while(!WSH.StdIn.AtEndOfStream) {
    var f = WSH.StdIn.ReadLine();
    var s = fso.OpenTextfile(f, 1).ReadAll();
    var m = s.match(/<item>(?:(?!<\/?item>)[\s\S])+<\/item>/g);
    for(var i=0; i<m.length; i++) {
        var m1 = m[i].match(/\bSoul Crystal\b.+\n(?:(?!\bid=).)+\bid="([^"]+)"/);
        var m2 = m[i].match(/\bproduction\b(?:(?!\bid=).)+\bid="([^"]+)"/);
        if(m1 && m2) WSH.Echo(m1[1] + ',' + m2[1]);
    }
}COPY
@if(0)==(0) echo off
dir /b *.xml | cscript -nologo -e:jscript "%~f0" > result.csv
pause & exit
@end
var xml = new ActiveXObject('Microsoft.XMLDOM');
var reg = /\bSoul Crystal\b/;
while(!WSH.StdIn.AtEndOfStream) {
    var f = WSH.StdIn.ReadLine();
    getXmlData(f);
}
function getXmlData(fileName) {
    xml.load(fileName);
    var nodes = xml.selectNodes('//item');
    for(var i=0; i<nodes.length; i++) {
        var s2 = nodes[i].lastChild.getAttribute('id');
        var childs = nodes[i].childNodes;
        for(var j=0; j<childs.length; j++) {
            if(childs[j].nodeName == '#comment' && reg.test(childs[j].text)) {
                var s1 = childs[j+1].getAttribute('id');
                WSH.Echo(s1 + ',' + s2);
                break;
            }
        }
    }
}COPY

TOP

这样行不?
@echo off&chcp 936
echo 进行中,请耐心等待
set "outfile=___output.csv"
cd.>"%outfile%"
for %%b in ("*.xml") do (
setlocal
echo,file,%%~b>>%outfile%
(for /f "skip=1 delims=" %%c in ('findstr /n .* "%%~b"') do (
set line1=
set /p line1=
set line2=%%c
if not defined item (
setlocal enabledelayedexpansion
if "!line1:<item>=!" neq "!line1!" (
for %%- in (1) do endlocal&set item=%%-) else endlocal
) else (
setlocal enabledelayedexpansion
if "!line1:Soul Crystal=!" neq "!line1!" (
set line3=!line2:* =!&set line3=!line3:~0,-2!
2>nul set /a !line3:id=,id!
for %%- in ("!id!") do endlocal&set o=%%~-&set match=1
if "!p!" == "!q!" endlocal
) else endlocal
if defined match (
setlocal enabledelayedexpansion
if "!line2:</item>=!" neq "!line2!" (
set line3=!line1:* =!&set line3=!line3:~0,-2!
2>nul set /a !line3:id=,id!
echo,!o!,!id!
endlocal&set o=&set match=&set item=
) else endlocal
)
)
))<"%%~b">>"%outfile%"
endlocal
)
echo,&echo 完成&pauseCOPY

TOP

返回列表