使用Windows批处理脚本递归重命名基于内容的多个xml文件

时间:2015-01-23 09:26:53

标签: batch-file

您好我有要求,而且我对批处理脚本非常新。我在名为APJ01.xm APJ02.xml .... APJ0n.xml的文件夹中有多个xml文件。我必须根据标记值976064101中的内容重命名所有这些xml。这里我必须拉976064101并使用相应的XML文件重命名。我试过这个开始在标签内拉取值

@ECHO OFF
SET InFile=C:\ramesh_personal\WIN_SRC\APJ_01.txt

FOR /F "tokens=*" %%A IN (
  'FINDSTR "<SOM_SalesOrderID>" "%InFile%" ^| FINDSTR "</SOM_SalesOrderID>"'
) DO CALL :FindString "%%A"
pause
GOTO :eof

:FindString
SET String=%~1
SET String=%String:*wordA =%
SET String=%String: wordB=`%
FOR /F "tokens=1 delims=`" %%A IN ('ECHO.%String%') DO ECHO.%%A]
GOTO :eof

但这并没有给出价值,它说文件第1行太长了。

有人可以就此提出一个想法

1 个答案:

答案 0 :(得分:1)

这个脚本可以工作:

@ECHO OFF
@SETLOCAL enableextensions disabledelayedexpansion
SET "InFile=C:\ramesh_personal\WIN_SRC\APJ_01.txt"

FOR /F "tokens=*" %%A IN (
  'FINDSTR "<SOM_SalesOrderID>" "%InFile%" ^| FINDSTR "</SOM_SalesOrderID>"'
  ) DO (
    SET "String=%%A"
    CALL :FindString
)

pause

ENDLOCAL
GOTO :eof

:FindString
SET "String=%String:*<SOM_SalesOrderID>=%"
SET "String=%String:</SOM_SalesOrderID>=`%"
FOR /F "tokens=1 delims=`" %%X IN ('ECHO %String%') DO (
  ECHO %%X]
) 
GOTO :eof

注意:

    如果某行包含disabledelayedexpansion ,请
  • !
  • 引用所有set "variable=value",例如SET "String=%String:*<SOM_SalesOrderID>=%"
  • CALL :FindString代替CALL :FindString "%%A"
  • %%X %%variable过程中的{隐式)嵌入式FOR循环中的:FindString@ECHO OFF >NUL @SETLOCAL enableextensions disabledelayedexpansion SET "InPath=C:\ramesh_personal\WIN_SRC" For /F "tokens=*" %%i in ('dir /B "%InPath%\*.txt"') do ( SET "InFile=%InPath%\%%i" FOR /F "tokens=*" %%A IN ( 'FINDSTR "<SOM_SalesOrderID>" "%InPath%\%%i" ^| FINDSTR "</SOM_SalesOrderID>"' ) DO ( set "OuName=x" SET "String=%%A" CALL :FindString ) ) ) :endlocal @ENDLOCAL goto :eof :FindString SET "String=%String:*<SOM_SalesOrderID>=%" SET "String=%String:</SOM_SalesOrderID>=`%" FOR /F "tokens=1 delims=`" %%X IN ('ECHO %String%') DO ( rem ECHO %%X set "OuName=%%X" call :renFile "%InFile%" ) GOTO :eof :renFile echo "%~f1" "%~dp1%OuName%%~x1 GOTO :eof

编辑获取目录中的所有文件

FINDSTR

FOR /F "tokens=*" %%A IN ( 'type "%InPath%\%%i" ^|FIND "<SOM_SalesOrderID>" ^| FIND "</SOM_SalesOrderID>"' ) DO ( 行太长消息可以通过逐行读取文件来解决:

CrLf

文件中的行分隔符是什么?类似DOS的Lf,类似UNIX的Cr或类似MAC的XML

附录:限制:尽管FIND可用于扫描大型文件,但它不会检测到任何位于一行以上的字符串超过 1070 的字符串(带有没有回车)这使得在搜索二进制或 FOR /F "tokens=*" %%A IN ( 'FINDSTR "<SOM_SalesOrderID>" "%InPath%\%%i" ^| FINDSTR "</SOM_SalesOrderID>"' ) DO ( 文件类型时使用有限。


编辑II :根据this article on FINDSTR 'Line Length limits'指定为命令行参数的文件或通过/ F:FILE选项没有已知的行长度限制,但管道数据和重定向输入限制为每行8191个字节

所以摆脱

的重定向输入
  FOR /F "tokens=*" %%A IN (
    'FINDSTR "<SOM_SalesOrderID>" "%InPath%\%%i"'
    ) DO (

并改为使用next命令:

 FINDSTR "<SOM_SalesOrderID>" "C:\ramesh_personal\WIN_SRC\APJ_01.txt"

但是,请确保下一个命令按预期工作(首先是最重要的):

:FindOuName

如果不是这种情况,请考虑切换到另一种脚本语言(PowerShell,VBScript或JScript)


编辑III 在程序@ECHO OFF >NUL @SETLOCAL enableextensions disabledelayedexpansion SET "InPath=D:\bat\files" For /F "tokens=*" %%i in ('dir /B "%InPath%\*.XML"') do ( SET "InFile=%InPath%\%%i" @echo InFile "%InPath%\%%i" set "OuName=x" for /L %%G in (2, 1, 20) do ( CALL :InnerLoop %%G %%i ) call :renFile "%InPath%\%%i" ) :endlocal @ENDLOCAL goto :eof :InnerLoop if "%OuName%"=="x" ( for /F "usebackq tokens=%1* delims=<" /F %%A in ("%InPath%\%2") do ( SET "String=x%%Ay" CALL :FindOuName %%G ) ) goto :eof :FindOuName rem @echo on SET "String=%String:>y=€€€y%" SET "String=%String:"=řřř%" if not "%String%"=="xy" ( rem echo %1 "%String:&=^&%" if "%String:~0,18%"=="xSOM_SalesOrderID>" ( set "OuName=%String:*xSOM_SalesOrderID>=%" ) ) @echo off GOTO :eof :renFile if not "%OuName%"=="x" ( echo RENAME "%~f1" "%OuName:y=%%~x1" ) GOTO :eof 中有一些不明确,黑暗的特殊性,这是有效的

d:\bat>D:\bat\StackOverflow\28106690.bat
InFile "D:\bat\files\APJ_02.xml"
RENAME "D:\bat\files\APJ_02.xml" "976065279.xml"
InFile "D:\bat\files\APJ_02formatted.xml"
RENAME "D:\bat\files\APJ_02formatted.xml" "976065279.xml"
InFile "D:\bat\files\sl.xml"

<强>输出

%ii%

编辑IV 具有下一次更改的最终版本:

  • 自制的计数器for /L %%G ...而不是:FindOuName循环
  • 简化程序":在实际测试的XML标记中出现了@ECHO OFF >NUL @SETLOCAL enableextensions disabledelayedexpansion set "InPath=D:\bat\files" for /F "tokens=*" %%i in ('dir /B "%InPath%\*.XML"') do ( set "InFile=%InPath%\%%i" echo( echo InFile "%InPath%\%%i" set /A "ii=0" set "String=noForLoop" set "OuName=noNewName" call :InnerLoop call :renFile "%InPath%\%%i" rem pause >nul ) @ENDLOCAL goto :eof :InnerLoop set /A "ii+=1" set "String=noForLoop" if "%OuName%"=="noNewName" ( for /F "usebackq tokens=%ii%* delims=<" /F %%A in ("%InFile%") do ( set "String=x%%Ay" call :FindOuName ) ) else ( goto :eof ) if "%String%"=="noForLoop" goto :eof if %ii% LSS 31 ( goto :InnerLoop ) else ( echo Max. limit of tokens in a FOR command reached ) goto :eof :FindOuName set "String=%String:"='%" rem echo %ii% "%String:~0,18%" if "%String:~0,18%"=="xSOM_SalesOrderID>" ( set "OuName=%String:*xSOM_SalesOrderID>=%" ) GOTO :eof :renFile if not "%OuName%"=="noNewName" ( echo RENAME "%~f1" "%OuName:y=%%~x1" echo SOM_SalesOrderID found in iteration #%ii% ) else ( echo SOM_SalesOrderID not found in %ii% iterations ) GOTO :eof :: end of batch script 双引号
  • 公开了迭代次数以及是否达到了最大值。 FOR命令中的标记限制(31)

剧本:

d:\bat>D:\bat\StackOverflow\28106690.bat

InFile "D:\bat\files\APJ_02.xml"
RENAME "D:\bat\files\APJ_02.xml" "976065279.xml"
SOM_SalesOrderID found in iteration #5

InFile "D:\bat\files\APJ_02formatted.xml"
RENAME "D:\bat\files\APJ_02formatted.xml" "976065279.xml"
SOM_SalesOrderID found in iteration #3

InFile "D:\bat\files\smLayoutFormatted.xml"
SOM_SalesOrderID not found in 3 iterations

InFile "D:\bat\files\smLayoutRaw.xml"
Max. limit of tokens in a FOR command reached
SOM_SalesOrderID not found in 31 iterations

输出

smLayoutRaw.xml

仅供参考:POWERSHELL -NonInteractive -Command Export-StartLayout –As XML –Path .\files\smLayoutRaw.xml 是我的开始菜单布局

导出
*Formatted.xml

和{{1}} =重新排列文件以在一行中保存一个XML标记