【问题标题】:How to cope with inconsistent filename formatting of %* in batch files如何处理批处理文件中 %* 的文件名格式不一致
【发布时间】:2013-03-11 19:14:24
【问题描述】:

我写了一个视频转换批处理,用户可以简单地将他的视频从任何磁盘或分区拖放到批处理上,之后转换后的视频将保存在特定磁盘上的特定位置。

代码如下所示

@echo off
%~d0
cd %~p0
for %%f in (%*) do ...
pause

实际问题在于(%*)
当我的文件名称中有一个右圆括号时,批处理将不起作用。为了解决这个问题,我使用了("%*"),但这不适用于名称中包含空格的文件或多个文件。
我也试过(%~*),但这是无效的。

经过一些研究,我注意到,当我在批处理中删除多个名称为 file(test)file test 的文件时,%* 解析为

file(test) "file test"

这意味着文件名可以有引号,也可以不...

我的问题是:我该如何处理?
理想情况下,我希望 %* 解析为 "file(test)" "file test"(两个名称都用引号括起来)

【问题讨论】:

  • 旁注:请注意,您可以使用pushd %~dp0 而不是%~d0 + cd %~p0。附带的好处是,如果你想回到原来的文件夹,你可以在最后做一个popd
  • 替代pushd,您可以使用cd /d %~dp0

标签: windows batch-file drag-and-drop


【解决方案1】:

除了使用for 循环之外,您还可以使用每个参数调用一个子例程,一次一个。

:nextArgument
set arg=%~1
if not defined arg goto :eof
call :processFile "%arg%"
shift
goto nextArgument

:processFile
set file=%~1
echo "%file%"
:: do your processing here
goto :eof

这将一次处理一个以空格分隔的参数(但引用的参数可以包含空格),并将它们传递给 processFile 例程。我使用%~1 首先从参数中删除引号,然后在调用processFile 时重新添加引号。这样我就知道当我到达 processFile 时,所有内容都有引号。

【讨论】:

  • +1 有趣的解决方案。不过,我会在接受之前等待其他答案(希望您能理解)。
  • 我决定提前接受你的回答,因为我很不耐烦;)而且,因为我从这个答案中学到了很多东西,而且我的代码最终比我的原始代码更具可读性(因为for强迫我把所有的电话放在一条线上)
  • @Nolonar:可能不是for 迫使您将所有呼叫放在同一行上,但您可能不知道多行语法。在循环体周围使用方括号 (())。这将允许您将循环体的各个命令放在自己的行中,如下所示:for ... do ( command1 command2 ... ) ... (结束 ) 可以单独一行)。尽管如此,使用goto 循环而不是for 也有其好处,学习这种技术肯定不会有什么坏处。
  • @Nate:在作业周围添加" 通常是个好主意:set "arg=%~1"。这将允许您转义名称中允许但在批处理文件中具有特殊含义的字符(例如&)。
  • +1, @Nate 就像 Andriy M 建议的那样,您应该将其括在引号中,并且不要在通话中扩展 arg,否则您会遇到插入符号 ^ 的问题,更好的访问稍后通过 varname 延迟扩展。
猜你喜欢
  • 2011-06-15
  • 1970-01-01
  • 2012-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-26
相关资源
最近更新 更多