如何使SHIFT与批处理文件中的%*一起使用

bar*_*uin 35 windows-xp batch-file

在我在Windows XP上的批处理文件中,我想使用%*扩展到除第一个之外的所有参数.
测试文件(foo.bat):

@echo off
echo %*
shift
echo %*
Run Code Online (Sandbox Code Playgroud)

呼叫:

C:\> foo a b c d e f
Run Code Online (Sandbox Code Playgroud)

实际结果:

a b c d e f
a b c d e f
Run Code Online (Sandbox Code Playgroud)

期望的结果:

a b c d e f
b c d e f
Run Code Online (Sandbox Code Playgroud)

我怎样才能达到预期的效果?谢谢!!

dbe*_*ham 21

如果CMD.EXE以这种方式工作,那会不会很棒!不幸的是,没有一个好的语法可以做你想要的.您可以做的最好的事情是自己解析命令行并构建一个新的参数列表.

像这样的东西可以工作.

@echo off
setlocal
echo %*
shift
set "args="
:parse
if "%~1" neq "" (
  set args=%args% %1
  shift
  goto :parse
)
if defined args set args=%args:~1%
echo(%args%
Run Code Online (Sandbox Code Playgroud)

但上面有问题,如果一个参数包含特殊字符,例如^,&,>,<,|那逃走的,而不是引用.

参数处理是Windows批处理编程的许多薄弱环节之一.对于几乎所有解决方案,都存在导致问题的异常.


cyb*_*onk 6

那\xc2\xb4s 很简单:

\n\n
setlocal ENABLEDELAYEDEXPANSION\n  set "_args=%*"\n  set "_args=!_args:*%1 =!"\n\n  echo/%_args%\nendlocal\n
Run Code Online (Sandbox Code Playgroud)\n\n

与评论相同:

\n\n
:: Enable use of ! operator for variables (! works as % after % has been processed)\nsetlocal ENABLEDELAYEDEXPANSION\n  set "_args=%*"\n  :: Remove %1 from %*\n  set "_args=!_args:*%1 =!"\n  :: The %_args% must be used here, before \'endlocal\', as it is a local variable\n  echo/%_args%\nendlocal\n
Run Code Online (Sandbox Code Playgroud)\n\n

例子:

\n\n
lets say %* is "1 2 3 4":\n\nsetlocal ENABLEDELAYEDEXPANSION\n  set "_args=%*"             --> _args=1 2 3 4\n  set "_args=!_args:*%1 =!"  --> _args=2 3 4\n\n  echo/%_args%\nendlocal\n
Run Code Online (Sandbox Code Playgroud)\n\n

评论:

\n\n
    \n
  • !如果任何参数包含或&字符,则不起作用
  • \n
  • 参数之间的任何额外空格都不会被删除
  • \n
  • %_args%必须在之前使用endlocal,因为它是局部变量
  • \n
  • 如果没有输入参数,%_args%则返回* =
  • \n
  • 如果仅输入 1 个参数,则不会移动
  • \n
\n

  • 正如所写,这是危险的错误,因为第一个参数的值可能会在后续参数中重复,并且您的代码将删除这两个参数。这可以通过使用“*”删除第一个实例中的所有内容来解决:“set _args=!_args:*%1=!”。其他无法修复的问题是如果`%1`包含`!`或`=`将会失败。 (6认同)