用于解析XML文件并将文件复制到不同文件夹

时间:2018-05-10 03:00:17

标签: batch-file cmd

我正在撰写目前看起来像这样的批处理文件( test.bat ):

SET DIR_WORKING=%cd%
SET DIR_RELEASE=%DIR_WORKING%\Release

for /F "tokens=1,* delims=]" %%p in ('c:\WINDOWS\System32\find.exe "?define TRIALFILE" %DIR_WORKING%\Include.wxi') do (
   set PFILE=%%p

   for /F "tokens=*" %%s in ("%PFILE%") do set PFILE=%%s

   set PFILE="%PFILE:~23,250%"
   set PATCHFILE="%PFILE:~0,-3%"]

   COPY "%PATCHFILE" %DIR_RELEASE%
)

我一直在努力解决一个名为 Include.wxi 的XML文件,获取一些.txt文件路径,然后将这些.txt文件复制到发布文件夹。

这是 Include.wxi 的样子:

<?xml version="1.0" encoding="utf-8"?>
<Include>
   <?define TRIALFILE001="%DIR_WORKING%\Users\K\Documents\Test\v1.txt"?>
   <?define TRIALFILE002="%DIR_WORKING%\Users\K\Documents\Test\v2.txt"?>
</Include>

这就是我的文件结构:

File structure

我试图尽可能地简化问题。我真的试图解决这个问题,但是CMD总是给我最模糊的错误。我似乎无法弄清楚如何让嵌套的for循环工作。请帮忙

3 个答案:

答案 0 :(得分:2)

@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "filename1=%sourcedir%\q50264822.txt"
SET "DIR_WORKING=u:\destdir"
SET "DIR_RELEASE=%DIR_WORKING%\Release"
MD "%dir_release%" 2>nul

FOR /f "tokens=3delims=<?=>" %%a IN ('c:\WINDOWS\System32\find.exe "?define TRIALFILE" "%filename1%" ' ) DO (
 CALL ECHO(COPY "%%~a" "%DIR_RELEASE%"
)

GOTO :EOF

您需要更改sourcedirdestdir的设置以适合您的具体情况。

我使用了一个名为q50264822.txt的文件,其中包含include.wxi的数据,用于测试。

为了测试目的,所需的COPY命令仅为ECHO在您确认命令正确后,将ECHO(COPY更改为COPY以实际复制文件。附加>nul以取消报告消息(例如1 file copied

问题的根本在于,您没有调用delayed expansion的设施(#1常见问题解答/批次 - 使用search工具查找许多示例),因为您正在改变code block(带括号的系列命令)中变量的值

更复杂的是你使用兔子的耳朵。 SO上的标准做法是使用语法set "var=value"进行字符串赋值,因为这可以确保忽略行上的杂散尾随空格。 SO上的标准做法是不将引号分配给,因为这会在连接变量时产生适当删除不需要的引号的问题。

所以 - 建立变量后,创建目标目录(否则copy命令将创建一个文件)并使用2>nul来抑制目标中已存在的错误消息。

然后使用适当的分隔符从文件中读取相应的行o选择所需的文件名作为标记3%%a - 精神上注意它将被引用。

call copy将首先使用%%a~删除引号,然后引用并评估结果,替换为%dir_working%。评估在子shell中执行,因此不需要delayed expansion

答案 1 :(得分:1)

@echo on
setlocal

SET "DIR_WORKING=%cd%"
SET "DIR_RELEASE=%DIR_WORKING%\Release"

if not exist "%DIR_RELEASE%" md "%DIR_RELEASE%"

for /F "tokens=1-2 delims=<?>" %%p in ('
 ""%systemroot%\system32\find.exe" "?define TRIALFILE" "%DIR_WORKING%\Include.wxi""
') do call :copyfrom %%p %%q
exit /b

:copyfrom
if not "%~1" == "define" exit /b 1
copy /y "%~3" "%DIR_RELEASE%"
exit /b 0

使用特殊的xml标记字符进行分隔 在文件路径中有效。令牌1-2将获得缩进 和define ...=...define ...=...如果没有 发现缩进。

使用令牌调用标签:copyfrom将对待 使用cmdline规则的参数。令牌中的缩进将 被视为空间被忽略。 define将被视为参数1 并在标签上进行测试以验证。之前的xml标记名称 =字符将是参数2.复制的路径将是 在=字符之后,它将成为参数3。

for循环中的命令有两个以上的双引号 并且两端都有双引号,因此cmd将剥离外部 双引号,因此我在外面添加了额外的双引号, 所以他们被剥夺了。

答案 2 :(得分:1)

也许这就足够了:

@For /F Tokens^=2Delims^=^" %%A In ('Find "?define TRIALFILE" include.wxi') Do @Copy "%%A" Release 2>Nul