2

我正在尝试编写一个批处理文件以在 XP 的命令提示符下运行。我正在尝试获取遵循特定命名约定的特定路径中的文件列表。我需要将每个文件实例复制并重命名为静态名称,然后将其放到传输文件夹中。

由于文件可能需要一段时间才能进入传输文件夹,所以我需要在复制下一个文件之前检查,以免覆盖前一个文件。我无法使用SLEEP或者TIMEOUT因为我没有安装额外的工具包。我尝试不断循环回到一个START部分,直到文件被发送。

我注意到,如果我传递了循环中%%x设置的值for,如果我循环回该START部分几次,它似乎失去了它的值并且它被设置为空。所以我尝试设置一个变量来保存该值。

我似乎遇到了变量设置不正确或未清除的问题。最初它继续引用第一个文件,但现在它似乎根本没有设置。显示ECHO正确的值,但filename变量仍然为空。

有谁知道这样做的更好方法?提前感谢您的帮助,因为我已经浪费了一整天的时间!

这是批处理文件:

@ECHO "At the start of the loop" 
@for %%x in (C:\OUTBOUND\customer_file*) do (
@ECHO "In the loop" 
@ECHO "loop value =" 
@ECHO %%x
SET filename=%%x
@ECHO "filename ="
@ECHO %filename%
@ECHO ...ARCHIVE OUTBOUND CUSTOMER FILE
archivedatafile --sourcefile="%filename%" --archivefolder="..\archivedata\customer" --retentiondays=0
IF NOT %ERRORLEVEL%==0 GOTO ERROR
PAUSE
:START
IF EXIST l:\OutputFile (
@ping 1.1.1.1 -n 1 -w 30000
GOTO START
) ELSE (
COPY %filename% l:\OutputFile /Y
IF NOT %ERRORLEVEL%==0 GOTO ERROR
PAUSE
)
)
GOTO END
:ERROR
@echo off
@ECHO *************************************************************
@ECHO *                      !!ERROR!!                            *
@ECHO *************************************************************
:END
SET filename=
4

3 回答 3

4

foxidrive 提供了一个应该可以工作的脚本,但没有解释您的代码失败的原因以及他如何解决问题。

你有2个问题:

1)只要在循环中执行 GOTO,您的 FOR 循环就会立即中止。GOTO 目标标签的放置位置无关紧要 - GOTO 总是终止循环。Foxidrive 对 CALL 的使用完美 - 一旦 CALLed 例程返回,循环将继续。

2)您尝试在代码块中设置变量,然后在同一块中引用新值。%VAR%在解析语句时扩展,并且像 IF 和 FOR 这样的复杂命令在一次传递中全部解析一次。实际上,括号内的任何代码块都会一次性解析。因此 和 的值%ERRORLEVEL%%FILENAME%是恒定的 - 输入块之前存在的值。

正如 Endoro 所指出的,解决该问题的一种方法是使用延迟扩展。必须通过 using 启用延迟扩展setlocal enableDelayedExpansion,然后使用 扩展变量!VAR!。该值在执行时而不是解析时扩展。从命令提示符键入HELP SET以获取有关延迟扩展的更多信息。

但请注意,延迟扩展在与 FOR 循环一起使用时可能会导致其自身的问题,因为延迟扩展发生在 FOR 变量扩展之后:%%x如果值包含 a 将被破坏!。这个问题可以通过根据需要通过 SETLOCAL 和 ENDLOCAL 仔细切换延迟扩展 ON 和 OFF 来解决。

Foxidrive 的代码通过使用 CALL 避免了整个延迟扩展问题。他的 :NEXT 例程不在 FOR 循环内,因此每次调用时都会重新解析所有命令,因此不需要延迟扩展。

于 2013-05-23T11:38:40.497 回答
1

这可能有效 - 它未经测试:

@echo off
ECHO Starting...
for %%x in (C:\OUTBOUND\customer_file*) do call :next "%%x"
echo done
pause
goto :eof
:next
ECHO ...ARCHIVING OUTBOUND CUSTOMER FILE "%~1"
archivedatafile --sourcefile="%~1" --archivefolder="..\archivedata\customer" --retentiondays=0
IF ERRORLEVEL 1 GOTO :ERROR
:loop
echo waiting for file...
ping -n 6 localhost >nul
IF EXIST l:\OutputFile GOTO :loop
COPY "%~1" l:\OutputFile /Y
IF ERRORLEVEL 1 GOTO :ERROR
GOTO :EOF
:ERROR
ECHO *************************************************************
ECHO * !!ERROR!! in "%%x"
ECHO *************************************************************
pause
goto :EOF
于 2013-05-22T23:17:33.997 回答
0

尝试这个:

@echo off&setlocal
for %%x in (C:\OUTBOUND\customer_file*) do SET "filename=%%x"
ECHO %filename%
ECHO ...ARCHIVE OUTBOUND CUSTOMER FILE
archivedatafile --sourcefile="%filename%" --archivefolder="..\archivedata\customer" --retentiondays=0
IF NOT %ERRORLEVEL%==0 GOTO:ERROR
PAUSE
:START
IF EXIST l:\OutputFile ping 1.1.1.1 -n 1 -w 30000&GOTO:START
COPY "%filename%" l:\OutputFile /Y
IF NOT %ERRORLEVEL%==0 GOTO:ERROR
PAUSE
GOTO:END
:ERROR
echo off
ECHO *************************************************************
ECHO *                      !!ERROR!!                            *
ECHO *************************************************************
:END
SET "filename="

如果您使用代码块(ifforwith ( ))和变量值变化,您必须启用delayed expansion。如您所见,您不需要此代码中的代码块。

于 2013-05-22T20:16:00.113 回答