使用 XML 文件中的文件名来组织声音文件的批处理脚本
Batch script using file names from an XML file to organize sound files
我有以 ID 命名的声音文件。找到声音的唯一方法是翻遍具有每个文件名的参考资料库。
我想要实现的是找到 ID 的脚本,以及 'Path' 重命名文件和组织所述文件的脚本。
这是来自 XML 的数据,其中包含有关声音的信息:
<File Id="14518742" Language="SFX">
<ShortName>Creatures\Fish_Large_Swim_03.wav</ShortName>
<Path>SFX\Creatures\Fish_Large_Swim_03_9344E057.wem</Path>
</File>
任务要求:找到ID为14518742
的文件名<file ...
,例如14518742.ogg
。我想将文件移动到 <Path>
:
中存储的目录
SFX\Creatures\Fish_Large_Swim_03_9344E057
由于无能,我连ID都拿不到:
@FOR /F "delims= " %%i IN ('find "<File Id=" Bankinfo.xml') DO @(
@for /f "delims= " %%a in ("%%i") do @(
set %%i=%%a
set %id%=%%i
Rem This was an attempt to trim the string, thing is that I can't find out why this doesn't work, because percentage signs.
set %id%=%id:~-7,7%
)
)
pause
我无法解决尝试 trim 字符串的问题,我只能设法使用定界符。即使那样我也可能无法完成这个。
编辑 #2:由于 "put on hold as too broad" 进行了修订,并由于太长而对其进行了压缩。我会道歉,因为我不太了解脚本(至少使用 CMD)或关于如何在此站点上提问的任何适当礼仪。
您可以使用在包含所有 *.ogg 文件的目录中执行的以下批处理代码,并且还包含具有 XML 数据的文件 XmlFile.xml
:
注意:第三行delims=
之后<
和>
之间的字符必须是水平制表符。浏览器根据 HTML 标准将制表符显示并复制为单个 space 字符。
@echo off
setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq tokens=1* delims=< > " %%A in ("XmlFile.xml") do (
if "%%A" == "File" (
for /F "tokens=2 delims== " %%C in ("%%B") do set "OggFileName=%%~C.ogg"
) else if "%%A" == "Path" (
set "TargetPath=%%B"
set "TargetPath=!TargetPath:~0,-11!"
for /F "delims=" %%F in ("!TargetPath!") do set "NewFileName=%%~nxF.ogg"
if not exist "!TargetPath!" md "!TargetPath!"
if exist "!OggFileName!" (
move /-Y "!OggFileName!" "!TargetPath!\!NewFileName!"
) else (
echo There is no file !OggFileName! in folder %CD%.
)
)
)
endlocal
最外层的 FOR 处理从 XML 文件中读取的每一行,并将每个非空行拆分为两个字符串:
元素名称被分配给循环变量A
因为tokens=1
是File
,ShortName
,Path
和也 /File
其中最后一个应该被忽略,这就是为什么 /
没有在分隔符列表中指定的原因。
元素名称后space或>
之后的剩余行被分配给下一个循环变量B
是ASCII table之后的下一个字符A
因为 *
附加在 tokens=1
之后,用于此示例:
Id="14518742" Language="SFX">
Creatures\Fish_Large_Swim_03.wav</ShortName>
SFX\Creatures\Fish_Large_Swim_03_9344E057.wem</Path>
接下来对循环变量 A
的值进行区分大小写的比较,以识别需要处理的行。
元素名称为 File
的行包含属性值 Id
中 *.ogg 文件的文件名。另一个 FOR 用于使用等号和 space 字符作为分隔符来拆分分配给循环变量 B
的字符串。
从字符串 Id="14518742" Language="SFX">
中等号后的第二个子字符串 "14518742"
很有趣,这就是使用 tokens=2
的原因。这个不带双引号并附加了 .ogg
的字符串被分配给环境变量 OggFileName
供以后使用。
另一个感兴趣的元素是 Path
,其中包含文件夹路径以及 *.ogg 文件的文件名。
所以从分配给循环变量B
的字符串SFX\Creatures\Fish_Large_Swim_03_9344E057.wem</Path>
首先删除最后11个字符以获得目标文件夹路径字符串SFX\Creatures\Fish_Large_Swim_03_9344E057
.
再次使用命令FOR 将最后一个反斜杠后的字符串分配给环境变量NewFileName
,这应该是*.ogg 文件的新文件名.因为在使用 %%~nxF
而不是 %%~nF
之前读取扩展名 .wem
已经被删除,如果文件名包含一个点,它被解释为已经被截断的文件名作为文件扩展名分隔符.
接下来创建目录(如果不存在),如果当前目录中存在 *.ogg 文件,则使用新文件名将其移动到该目录中。
要移动文件并保持 ID 作为文件名,请使用下面的批处理代码,其中仅行确定环境变量的文件名 NewFileName
并延迟扩展对该环境变量的引用与命令 MOVE 与上面的批处理代码相比被删除了。
@echo off
setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq tokens=1* delims=< > " %%A in ("XmlFile.xml") do (
if "%%A" == "File" (
for /F "tokens=2 delims== " %%C in ("%%B") do set "OggFileName=%%~C.ogg"
) else if "%%A" == "Path" (
set "TargetPath=%%B"
set "TargetPath=!TargetPath:~0,-11!"
if not exist "!TargetPath!" md "!TargetPath!"
if exist "!OggFileName!" (
move /-Y "!OggFileName!" "!TargetPath!\"
) else (
echo There is no file !OggFileName! in folder %CD%.
)
)
)
endlocal
要了解使用的命令及其工作原理,请打开命令提示符 window,在其中执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。
echo /?
endlocal /?
for /?
if /?
move /?
set /?
setlocal /?
我有以 ID 命名的声音文件。找到声音的唯一方法是翻遍具有每个文件名的参考资料库。
我想要实现的是找到 ID 的脚本,以及 'Path' 重命名文件和组织所述文件的脚本。
这是来自 XML 的数据,其中包含有关声音的信息:
<File Id="14518742" Language="SFX">
<ShortName>Creatures\Fish_Large_Swim_03.wav</ShortName>
<Path>SFX\Creatures\Fish_Large_Swim_03_9344E057.wem</Path>
</File>
任务要求:找到ID为14518742
的文件名<file ...
,例如14518742.ogg
。我想将文件移动到 <Path>
:
SFX\Creatures\Fish_Large_Swim_03_9344E057
由于无能,我连ID都拿不到:
@FOR /F "delims= " %%i IN ('find "<File Id=" Bankinfo.xml') DO @(
@for /f "delims= " %%a in ("%%i") do @(
set %%i=%%a
set %id%=%%i
Rem This was an attempt to trim the string, thing is that I can't find out why this doesn't work, because percentage signs.
set %id%=%id:~-7,7%
)
)
pause
我无法解决尝试 trim 字符串的问题,我只能设法使用定界符。即使那样我也可能无法完成这个。
编辑 #2:由于 "put on hold as too broad" 进行了修订,并由于太长而对其进行了压缩。我会道歉,因为我不太了解脚本(至少使用 CMD)或关于如何在此站点上提问的任何适当礼仪。
您可以使用在包含所有 *.ogg 文件的目录中执行的以下批处理代码,并且还包含具有 XML 数据的文件 XmlFile.xml
:
注意:第三行delims=
之后<
和>
之间的字符必须是水平制表符。浏览器根据 HTML 标准将制表符显示并复制为单个 space 字符。
@echo off
setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq tokens=1* delims=< > " %%A in ("XmlFile.xml") do (
if "%%A" == "File" (
for /F "tokens=2 delims== " %%C in ("%%B") do set "OggFileName=%%~C.ogg"
) else if "%%A" == "Path" (
set "TargetPath=%%B"
set "TargetPath=!TargetPath:~0,-11!"
for /F "delims=" %%F in ("!TargetPath!") do set "NewFileName=%%~nxF.ogg"
if not exist "!TargetPath!" md "!TargetPath!"
if exist "!OggFileName!" (
move /-Y "!OggFileName!" "!TargetPath!\!NewFileName!"
) else (
echo There is no file !OggFileName! in folder %CD%.
)
)
)
endlocal
最外层的 FOR 处理从 XML 文件中读取的每一行,并将每个非空行拆分为两个字符串:
元素名称被分配给循环变量
A
因为tokens=1
是File
,ShortName
,Path
和也/File
其中最后一个应该被忽略,这就是为什么/
没有在分隔符列表中指定的原因。元素名称后space或
>
之后的剩余行被分配给下一个循环变量B
是ASCII table之后的下一个字符A
因为*
附加在tokens=1
之后,用于此示例:Id="14518742" Language="SFX"> Creatures\Fish_Large_Swim_03.wav</ShortName> SFX\Creatures\Fish_Large_Swim_03_9344E057.wem</Path>
接下来对循环变量 A
的值进行区分大小写的比较,以识别需要处理的行。
元素名称为 File
的行包含属性值 Id
中 *.ogg 文件的文件名。另一个 FOR 用于使用等号和 space 字符作为分隔符来拆分分配给循环变量 B
的字符串。
从字符串 Id="14518742" Language="SFX">
中等号后的第二个子字符串 "14518742"
很有趣,这就是使用 tokens=2
的原因。这个不带双引号并附加了 .ogg
的字符串被分配给环境变量 OggFileName
供以后使用。
另一个感兴趣的元素是 Path
,其中包含文件夹路径以及 *.ogg 文件的文件名。
所以从分配给循环变量B
的字符串SFX\Creatures\Fish_Large_Swim_03_9344E057.wem</Path>
首先删除最后11个字符以获得目标文件夹路径字符串SFX\Creatures\Fish_Large_Swim_03_9344E057
.
再次使用命令FOR 将最后一个反斜杠后的字符串分配给环境变量NewFileName
,这应该是*.ogg 文件的新文件名.因为在使用 %%~nxF
而不是 %%~nF
之前读取扩展名 .wem
已经被删除,如果文件名包含一个点,它被解释为已经被截断的文件名作为文件扩展名分隔符.
接下来创建目录(如果不存在),如果当前目录中存在 *.ogg 文件,则使用新文件名将其移动到该目录中。
要移动文件并保持 ID 作为文件名,请使用下面的批处理代码,其中仅行确定环境变量的文件名 NewFileName
并延迟扩展对该环境变量的引用与命令 MOVE 与上面的批处理代码相比被删除了。
@echo off
setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq tokens=1* delims=< > " %%A in ("XmlFile.xml") do (
if "%%A" == "File" (
for /F "tokens=2 delims== " %%C in ("%%B") do set "OggFileName=%%~C.ogg"
) else if "%%A" == "Path" (
set "TargetPath=%%B"
set "TargetPath=!TargetPath:~0,-11!"
if not exist "!TargetPath!" md "!TargetPath!"
if exist "!OggFileName!" (
move /-Y "!OggFileName!" "!TargetPath!\"
) else (
echo There is no file !OggFileName! in folder %CD%.
)
)
)
endlocal
要了解使用的命令及其工作原理,请打开命令提示符 window,在其中执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。
echo /?
endlocal /?
for /?
if /?
move /?
set /?
setlocal /?