批处理脚本参数中的空格

时间:2010-08-05 15:41:33

标签: cmd batch-file

我有一个批处理脚本,需要对每个参数执行操作。每个参数都是文件名(没有开关),当然文件名可能包含空格。批处理脚本可以通过将文件拖放到资源管理器中的.bat图标中,也可以通过在命令行输入文件来封闭,并用引号括起空格。

在批处理脚本中,处理带空格的参数存在问题。如果我按如下方式使用%*,则会忽略引号,并将空格之间的每个“单词”视为参数。

for %%x in (%*) do (
    echo %%x
)

我也尝试使用shift,这似乎也无法正常工作,阻塞了名称中带有空格的文件:

:next
if not %1 == "" (
    echo %1

    shift /1
    goto next
)

迭代所有参数的理想方法是什么?

在Bash中,人们可以简单地使用"$@"和Just Works™,但当然,Windows批处理脚本似乎并非如此。

3 个答案:

答案 0 :(得分:2)

for 变量引用的替换修饰符也允许使用~expanions。请参阅for command reference

使用"%%~x",您应该获得正确引用的参数,类似于bash处理"$@"的方式。

@echo off

setlocal enableextensions

for %%x in (%*) do (
    echo "%%~x"
)

人物,和;可用于分隔命令参数。见command shell overview。因此,您必须在包含这些字符的文件名周围加上引号。

如果将文件从资源管理器拖到.bat上,则只有在文件路径中有空格字符时,资源管理器才会正确引用该文件。例如,资源管理器不会引用D:\a,b,c.exe,因此cmd.exe会将其解析为三个单独的参数。

为了让脚本能够在资源管理器中拖放这些怪胎,你可以使用以下(丑陋)解决方法:

@echo off

setlocal enableextensions enabledelayedexpansion

set "args=%*"
set "args=%args:,=:comma:%"
set "args=%args:;=:semicolon:%"

for %%x in (%args%) do (
    set "filepath=%%~x"
    set "filepath=!filepath::comma:=,!"
    set "filepath=!filepath::semicolon:=;!"
    echo "!filepath!"
)

该脚本引入了一个辅助变量args,其中每个出现的麻烦字符都被占位符替换(请注意,冒号字符本身不能在Windows下的文件名中使用)。

for循环的主体使用另一个辅助变量filepath,该变量取消转换以产生原始路径。

答案 1 :(得分:0)

我创建了一个批处理“函数”,它可以“正确”解析参数并正确处理等号和分号。我想你会发现它可以帮助你解决这些问题。我的网站上有完整的详细信息和示例: http://skypher.com/index.php/2010/08/17/batch-command-line-arguments/

答案 2 :(得分:0)

我遇到类似问题的文件名包含等号(=),这会导致文件名被拆分为多个参数。我使用"%*"解决了这个问题。

如果您有一个包含空格的文件,例如foo bar baz.txt,会引用两次:""foo bar baz.txt""。现在双重双引号被转义:foo bar baz.txt,结果为%1 = foo%2 = bar%3 = {{ 1}}。所以这不起作用。

如果您的文件包含空格和/或等号,则可以使用:

baz.txt

现在,set input=""%*"" set input=%input:"=% your_program "%input%" 将被引用三次:foo bar=baz.txt。两个引号将被转义,"""foo bar=baz.txt"""变为input。对于第二行,双引号被替换为任何内容(已删除)。当您将"foo bar=baz.txt"输入input时,需要再次将引号括起来,否则它会将空格视为单独的输入!

如果您只有等号,那么your_program会将""%*""变为foo=bar=baz.txt""foo=bar=baz.txt""会以[{1}} = %1的身份输入您的计划。