我有一个批处理脚本,需要对每个参数执行操作。每个参数都是文件名(没有开关),当然文件名可能包含空格。批处理脚本可以通过将文件拖放到资源管理器中的.bat图标中,也可以通过在命令行输入文件来封闭,并用引号括起空格。
在批处理脚本中,处理带空格的参数存在问题。如果我按如下方式使用%*
,则会忽略引号,并将空格之间的每个“单词”视为参数。
for %%x in (%*) do (
echo %%x
)
我也尝试使用shift
,这似乎也无法正常工作,阻塞了名称中带有空格的文件:
:next
if not %1 == "" (
echo %1
shift /1
goto next
)
迭代所有参数的理想方法是什么?
在Bash中,人们可以简单地使用"$@"
和Just Works™,但当然,Windows批处理脚本似乎并非如此。
答案 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
的身份输入您的计划。