[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[文本处理] 求助批处理提取代码中的对应文本内容到新的文件

各位大佬,我想要将文本中的灯光参数复制出来,求教各位。
文本内容:
        <Light name="6" type="AreaLight" enabled="1" label="VRayLight001" layer="0">
                <Transform tx="-9.940223" ty="-2.93766" tz="0.0" sx="1.0" sy="1.0" sz="1.0" qx="-0.5" qy="0.5" qz="0.5" qw="0.5" qhex64="000000000000E0BF000000000000E03F000000000000E03F010000000000E03F"/>
                <Color usetemp="0" temperature="6500.0" R="1.0" G="1.0" B="1.0"/>
                <Intensity value="461.481518"/>
                <IntensityUnits value="Lumens"/>
                <InnerConeAngle value="22.0"/>
                <OuterConeAngle value="22.5"/>
                <Shape type="Sphere" width="5.713418" length="5.713418" LightType="Point"/>
                <tag value="Max.superclassof: light" />
                <tag value="Max.classof: VRayLight" />
                <tag value="Max.handle: 6" />
                <tag value="Max.isGroupHead: false" />
                <tag value="Max.isGroupMember: false" />
                <tag value="Max.parent.handle: 0" />
        </Light>
        <Light name="7" type="AreaLight" enabled="1" label="VRayLight002" layer="0">
                <Transform tx="-1.332195" ty="-1.77626" tz="0.0" sx="1.0" sy="1.0" sz="1.0" qx="-0.5" qy="0.5" qz="0.5" qw="0.5" qhex64="000000000000E0BF000000000000E03F000000000000E03F010000000000E03F"/>
                <Color usetemp="0" temperature="6500.0" R="1.0" G="1.0" B="1.0"/>
                <Intensity value="1103.490878"/>
                <IntensityUnits value="Lumens"/>
                <InnerConeAngle value="22.0"/>
                <OuterConeAngle value="22.5"/>
                <Shape type="Sphere" width="8.834931" length="8.834931" LightType="Point"/>
                <tag value="Max.superclassof: light" />
                <tag value="Max.classof: VRayLight" />
                <tag value="Max.handle: 7" />
                <tag value="Max.isGroupHead: false" />
                <tag value="Max.isGroupMember: false" />
                <tag value="Max.parent.handle: 0" />
        </Light>

文本中包含多段<Light name开头</Light>结束的参数,我想要每一段中的参数
tx -9.940223
ty -2.93766
tz 0.0
qx -0.5
qy 0.5
qz 0.5
R 1.0
G 1.0
B 1.0
Intensity 461.481518
width 5.713418
length 5.713418
LightType Point

用vbs的msxml2.domdocument(不确定是不是这么拼)
要是电脑在身边就帮你解决了

TOP

  1. rem 另存为 ANSI 编码
  2. ' & cls & cscript.exe /nologo /e:vbscript "%~f0" %* & pause & exit
  3. Dim oWshShell, oFSO, s, oStream, oRegExp
  4. Const file    = "1.txt"    '原文件。支持文件拖放,支持文件名作为命令行参数
  5. Const charset = "GBK"      '文件编码。支持Unicode和UTF-8
  6. Set oWshShell = CreateObject("WScript.Shell")
  7. Set oFSO = CreateObject("Scripting.FileSystemObject")
  8. s = oFSO.GetParentFolderName(WScript.ScriptFullname)
  9. oWshShell.CurrentDirectory = s
  10. Set oStream = CreateObject("ADODB.Stream")
  11. oStream.Type    = 2    'adTypeText
  12. oStream.Mode    = 3    'adModeReadWrite
  13. oStream.Charset = charset
  14. Set oRegExp = New RegExp
  15. oRegExp.Global     = True
  16. oRegExp.MultiLine  = True
  17. oRegExp.IgnoreCase = True
  18. oRegExp.Pattern    = "<Light\b[\s\S]+?"                       & _
  19.                      "\b(tx)=""(.+?)""[\s\S]+?"               & _
  20.                      "\b(ty)=""(.+?)""[\s\S]+?"               & _
  21.                      "\b(tz)=""(.+?)""[\s\S]+?"               & _
  22.                      "\b(qx)=""(.+?)""[\s\S]+?"               & _
  23.                      "\b(qy)=""(.+?)""[\s\S]+?"               & _
  24.                      "\b(qz)=""(.+?)""[\s\S]+?"               & _
  25.                      "\b(R)=""(.+?)""[\s\S]+?"                & _
  26.                      "\b(G)=""(.+?)""[\s\S]+?"                & _
  27.                      "\b(B)=""(.+?)""[\s\S]+?"                & _
  28.                      "\b(Intensity value)=""(.+?)""[\s\S]+?"  & _
  29.                      "\b(width)=""(.+?)""[\s\S]+?"            & _
  30.                      "\b(length)=""(.+?)""[\s\S]+?"           & _
  31.                      "\b(LightType)=""(.+?)""[\s\S]+?</Light>"
  32. If WScript.Arguments.Count > 0 Then
  33.     For Each s In WScript.Arguments
  34.         Call run(s)
  35.     Next
  36. Else
  37.     Call run(file)
  38. End If
  39. Sub run(ByVal file)
  40.     Dim s, i, oMatch, oSubMatches
  41.     If Not oFSO.FileExists(file) Then MsgBox "找不到文件 " & file : WScript.Quit()
  42.     oStream.Open()
  43.     oStream.LoadFromFile file
  44.     s = ""
  45.     For Each oMatch In oRegExp.Execute(oStream.ReadText())
  46.         Set oSubMatches = oMatch.SubMatches
  47.         For i = 0 To 24 Step 2
  48.             s = s & oSubMatches(i) & " " & oSubMatches(i + 1) & vbCrLf
  49.         Next
  50.         s = s & vbCrLf
  51.     Next
  52.     oStream.Close()
  53.     oStream.Open()
  54.     oStream.WriteText s
  55.     oStream.SaveToFile oFSO.GetBaseName(file) & ".out.txt", 2    'adSaveCreateOverWrite
  56.     oStream.Close()
  57.     WScript.Echo file & vbTab & oFSO.GetBaseName(file) & ".out.txt"
  58. End Sub
复制代码

QQ 20147578

TOP

本帖最后由 77七 于 2023-4-29 11:10 编辑
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. (for /f "delims=" %%a in ('type "1.txt"') do (
  4. for %%b in (%%a) do (
  5. if not defined str (
  6. set "str=%%b"
  7. ) else (
  8. set "#!str!=%%b"
  9. if "%%b" equ "value" (
  10. set "str=!str:~1! %%b"
  11. ) else (
  12. set "str=%%b"
  13. )
  14. )
  15. )
  16. if defined #LightType (
  17. for %%c in (tx ty tz qx qy qz R G B Intensity width length LightType) do (
  18. for /f tokens^=1^-2delims^=^"^=^# %%d in ('set #%%c ^|findstr /v "type IntensityUnits"') do (
  19. echo %%d %%e
  20. )
  21. )
  22. set #LightType=
  23. )
  24. ))>2.txt
  25. endlocal
  26. pause
复制代码
效率过低,仅供参考。
bat小白,请多指教!谢谢!

TOP

像这种情况,楼主应当把要处理的文本发上来一个到网盘:
1.复制文本片段,有时会与源文本产生差异。比如水平制表符会变成4个空格。
2.文本格式可能会有差异,一般来说cmd默认处理ANSI编码的文本,如果是其它格式还需要特殊手段。

TOP

本帖最后由 newswan 于 2023-4-29 11:50 编辑

输入文件a.txt 输出文件 b.txt  UTF8编码
powershell 比较简单
  1. $reg = '^(name|tx|ty|tz|qx|qy|qz|R|G|B|Intensity|width|length|LightType)="(.*)"'
  2. $f1 = Get-Content -Encoding UTF8 -Raw "a.txt"
  3. $f2 = $f1 -replace '([^\s=]*="[^"]*")',"`n`$1`n" -split "`n" -match "="
  4. $f2 -match $reg -replace '"' -replace "="," " | Out-File -Encoding UTF8 "b.txt"
复制代码
多提取了一个,name

TOP

回复 1# eulb

假设灯光文本为1.txt,并已保存为ANSI编码格式,下载gawk(http://bcn.bathome.net/tool/4.1.0/gawk.exe)后执行:
  1. gawk "BEGIN{split(\"tx,ty,tz,qx,qy,qz,R,G,B,Intensity,width,length,LightType\",dat, \",\");for (i=1; i<=length(dat); i++)tA[dat[i]]}/\<Light name=/{print;while((getline)>0){if($0~/<\/Light>/){next};split($0,dat,\"[= \042]+\");for (i=1; i<=length(dat); i++)if(dat[i] in tA)print dat[i],dat[i+1]}}" 1.txt>2.txt
复制代码
2.txt即为你所需要的文档

TOP

非常感谢各位的帮忙。
我主要是用于UE4的外部文件导入,但是只能导入模型不能导入灯光,所以只能手动获取灯光参数再生成灯光。
UE4里面的文本分割只能分割一次,所以一开始觉得需要提取出来做成表格再导进去生成。
不过昨晚睡觉的时候想到了解决办法,刚刚实践了一下,算是成功了。
分割文本的时候,它只会把分割结果分成前后2个部分,我把每一次<Light name分割的后部分再分割,每一次结果都保存起来。
又因为每次只分割第一个关键词,所以前面分割的部分后面跟着的长串内容不会用到,除了占用空间外,倒是不影响我获取对应位置的参数。
总之还是很感谢各位的热心帮助。

TOP

返回列表