【问题标题】:Prevent Windows command-interpreter (FOR) from treating list as wildcards?防止 Windows 命令解释器 (FOR) 将列表视为通配符?
【发布时间】:2013-02-04 18:30:03
【问题描述】:

我正在尝试编写一个带有几个参数的批处理文件,后跟一个或多个可选文件名(可能包括通配符),并在某些时候处理每个可选文件名,但 for 命令保留试图扩展它们,所以即使只是打印它们也行不通。

我查看了帮助 (for /?),但似乎没有任何开关可以防止这种情况发生。我尝试使用单引号、双引号和反引号以及 /f,但似乎没有任何效果。

以下命令按预期工作:

> for %i in (foo bar baz) do @echo %i
foo
bar
baz

以下命令不会:

> for %i in (foo bar baz really?) do @echo %i
foo
bar
baz

以下,甚至更少:

> ren > reallyz
The syntax of the command is incorrect.

> dir /b really*
reallyz

> for %i in (foo bar baz really?) do @echo %i
foo
bar
baz
reallyz

有没有办法让 Windows 命令解释器将传递的列表视为字符串,而不是尝试将其解释为文件名通配符?

【问题讨论】:

  • 您是否尝试过使用插入符号“^”转义问号,如 (foo bar baz really^?)在命令行上运行与从批处理文件运行时更改。
  • 是的,转义它不起作用(此外,即使它确实如此,那么用户在调用批处理文件时必须记住转义它们,这当然是一个不理想的接口,因为它与传递文件名的其他用途不一致)。

标签: for-loop batch-file wildcard command-prompt wildcard-expansion


【解决方案1】:

否 - 简单的 FOR 命令将始终扩展 *? 通配符。

您需要使用 GOTO 循环来执行您想要的操作。 SHIFT 命令可以访问所有参数。

@echo off
:argLoop
if "%~1" neq "" (
  echo %1
  shift /1
  goto :argLoop
)

您很可能想要对参数做更多的事情,然后打印它们。通常,您会将它们存储在变量“数组”中以备后用。

@echo off
setlocal

set argCnt=1
:argLoop
if "%~1" neq "" (
  set "arg.%argCnt%=%~1"
  set /a argCnt+=1
  shift /1
  goto :argLoop
)
set /a argCnt-=1

:: Show Args
setlocal enableDelayedExpansion
for /l %%N in (1 1 %argCnt%) do echo arg.%%N = !arg.%%N!

【讨论】:

  • 很好,我已经考虑过了,但是使用shift 是不可撤销的(它会永久改变参数并且没有/reset 开关或接受否定参数),因此我不能稍后在批处理文件中访问它们(即前两个强制参数)。我想我也可以将前两个推送到 env-vars,但是因为我需要使用路径字符串选项(%~dp1%~n2...),所以将它们放在 env-vars 中是不愉快的(你不能这样做使用 vars,即 %~nfoobar% 将无法正常工作)。我必须通过另一个for 来运行它,但值得一试……
  • @Synetech - 是的,这就是我建议将值存储在变量中的原因。额外的 FOR 循环很冗长,但速度很快。如果您提前知道需要哪些变体,则可以保存多个值的副本,每个副本都有不同的扩展修饰符。
  • 好的,看起来可以了。我更改了可选参数循环的起始索引。我还必须使用 double-for-loop 来访问前两个参数中的每一个(例如,for /l %%i in (2,1,2) do for %%j in (!arg.%%i!) do echo [%%~pnj] 用于第二个),但至少它有效。 (这让原本应该是一个相对简单的批处理文件变得非常复杂,但它仍然比我编写一个完整的、已编译的 C++ 程序更简单——我将不得不研究集成 zip、7zip 等函数。最低限度。)谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-25
相关资源
最近更新 更多