【问题标题】:For loop in Windows batch file: Error: "The syntax of the command is incorrect"Windows 批处理文件中的 For 循环:错误:“命令的语法不正确”
【发布时间】:2013-11-15 20:35:34
【问题描述】:

这是我在此线程中提出的问题的后续行动: Extracting string after last instance of delimiter in a Batch file

我正在编写一个批处理文件,该文件采用未知数量的字符串作为参数,这些字符串表示来自 java 程序(调用 .bat)的目录。这些目录保存在一个名为“dirs”的“数组”中。

for /F "tokens=2 delims==" %%z in ('set dirs[') do (
    set "parm=%~1"
    for %%a in (%parm:\= %) do set folder=%%a
    echo %folder%
    shift
)

“dirs”数组将保留实际目录而不以任何方式更改它,最终我将使用它与 xcopy 作为要从中复制的目录。 Parm 将实际参数放入批处理文件并对其进行操作以提取目录的最后一部分。名为“文件夹”的变量存储此目录名称并将其打印到命令行。但是,当我运行程序时,我经常收到一条错误消息,提示“命令的语法不正确”。我尝试缩小问题的确切位置,并且肯定在上述循环内。为了使外循环工作,是否必须以某种方式操作 %%z ?当我用一个简单的“echo %%z”替换它的内容时,循环会起作用,所以这让我想知道这是否是问题所在。

编辑:这是更新后的循环,包括 xcopy 行:

for /F "tokens=2 delims==" %%z in ('set dirs[') do (
set "param=%~1"
set param=!param:\= !
for %%a in (!param!) do set lastDir=%%a
    echo !lastDir!
XCOPY %%z\*.* !outdrive!:\!dir!\!lastDir! /C /S /D /Y /I
shift
)

如果您需要知道,“outdrive”是外部硬盘,“dir”是程序前面创建的备份目录,lastDir 应该是不言自明的。它是文件夹名称,即“图片”或“文档”

最终编辑:

感谢所有回复的人。我因为之前没有看到答案而自责,但我已经找到了一些可以按预期工作的代码。这是当前所在的循环,运行正常:

for /F "tokens=2 delims==" %%z in ('set dirs[') do (
    set param=%%z
    set param=!param:\= !
    for %%a in (!param!) do set lastDir=%%a
    XCOPY %%z\*.* !outdrive!:\!dir!\!lastDir! /C /S /D /Y /I
)

我没有使用传入批处理文件的参数,而是直接从“dirs”数组工作。然后,我将一个不同的变量设置为指定的目录字符串,并对该变量进行操作,而不是存储在数组中的字符串。

【问题讨论】:

  • 只是answered today。不是相同的代码,而是相同的问题。请根据需要进行调整。
  • 还有,为什么要遍历 dirs 数组而不使用数据?并且,如果 dirs 数组已从通过 shift 迭代检索的参数填充,则使用参数,不再使用参数,那么 %1 将具有什么值?
  • 我最终将使用“dirs”数组,此时我已经修剪了循环以进行调试。 “dirs”不是通过使用 Shift 迭代来填充的,我使用了一个稍微复杂的系统来获取“dirs”数组的值,而无需操作批处理输入参数。至于链接,我明白他们在说什么,但我没有看到我的哪些变量是在循环之外声明的,然后在循环内部进行了更改。我在循环内使用的所有变量都是在循环内创建的,所以我对链接中的代码之间的关系有点困惑。
  • 在第一次使用!var! 构造之前的某个时间,您需要一行SETLOCAL ENABLEDELAYEDEXPANSION 来激活delayedexpansion 模式。直接在@echo off 之后就可以了。 SHIFT 在这种情况下无效。它移动过程参数的索引。
  • 我的程序顶部确实有该行。我刚刚让我的程序开始工作,我会将最终循环作为第二次编辑发布在我的主帖中,以供未来的读者阅读。谢谢大家的帮助!

标签: batch-file syntax command


【解决方案1】:

如果您需要在循环中使用变量,请使用延迟扩展和 !variables! 的更改语法。

shift 命令对循环变量没有任何作用。

【讨论】:

  • 非常感谢,“!”解决了这个问题。至于“转变”,你是对的,它什么也没做。有没有办法访问/转换循环中的变量?
  • shift 更改为pause,当你按下一个键时,它会显示你的每一次传球。
  • 这个批处理文件应该在没有任何用户输入的情况下运行,所以我不希望它依赖于监视命令行的用户。现在它只是一遍又一遍地打印图片(第一个目录),并且移位没有效果。我希望有一种方法可以做与 shift 相同的事情,这样我就可以在循环的每次迭代中更改字符串。
  • 在这种情况下,您没有正确使用延迟扩展。在问题底部添加您正在使用的代码。
  • 我刚刚添加了当前代码。我很抱歉,我似乎无法正确设置间距
【解决方案2】:

根据更新的信息,这应该会显示您需要的命令,并且此代码 sn-p 中不需要延迟扩展。

@echo off
set outdrive=E
set dir=backup

set dirs[1]=c:\folders1
set dirs[2]=c:\folders2
set dirs[3]=c:\folders3
set dirs[4]=c:\folders4

for /F "tokens=2 delims==" %%z in ('set dirs[') do (
echo XCOPY "%%z\*.*" "%outdrive%:\%dir%\%%~nxz\" /C /S /D /Y /I
)
pause

【讨论】:

  • 非常感谢。我只看到一个问题,那就是我不知道“dirs”数组中有多少个目录,所以第一部分(设置 dirs[1]=.....)有点困难。我确实找到了一种方法来做到这一点,我正在为自己没有早点看到它而自责。我将把它作为编辑添加到我的第一篇文章中。非常感谢你 foxidrive,你一直在帮助我朝着正确的方向前进!
  • 我循环中的代码与您的最终编辑完全相同 - 不使用延迟扩展。 %%~nxz 是字符串中的最后一个文件夹(或文件名)。 FOR /? 参见最后一页的帮助
  • 糟糕,你完全正确!该代码确实有效,除了我在命令窗口中不断收到错误消息说它找不到指定的驱动器。我似乎无法弄清楚它从哪里得到这个。我会做更多的挖掘,但无论哪种方式,它现在都在整体上工作。非常感谢,我会接受这个作为答案=)
  • 嗯,这很奇怪。我取出了一些被注释掉的代码,它就像一个魅力......系统尝试运行使用 :: 注释掉的命令是否常见?也许我应该改用 REM?
  • 在循环中使用 :: 时会导致问题(仅在某些行中,例如在最后一个括号之前),因此在循环中使用 REM 总是更安全。我很高兴你把它解决了。
猜你喜欢
  • 2016-02-24
  • 1970-01-01
  • 1970-01-01
  • 2016-04-09
  • 2013-01-25
  • 2018-01-27
  • 1970-01-01
  • 2013-03-12
  • 2011-01-16
相关资源
最近更新 更多