我想写一个batch file在XP上的命令提示符下运行。 我正在尝试获取特定path中遵循特定命名约定的文件列表。 我需要将每个文件实例复制并重命名为静态名称,并将其放到传输文件夹中。
由于文件可能需要一点时间才能进入传输文件夹,因此在复制下一个文件之前,我需要检查以确保不覆盖以前的文件。 我无法使用SLEEP
或TIMEOUT
因为我没有安装额外的工具包。 我尝试只是不断循环回到START
部分,直到文件被发送。
我注意到,如果我传递了在for
循环中设置的%%x
值,如果我多次循环回到START
部分,它似乎失去了它的值,它被设置为无。 所以我试图设置一个variables来保存值。
我似乎没有正确设置或不清除variables的问题。 原来它一直在引用第一个文件,但现在似乎并没有被设置。 ECHO
显示正确的值,但filename
variables仍为空。
有没有人知道这样做的更好方法? 预先感谢您的帮助,因为我已经浪费了一整天的时间!
这是batch file:
@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=
foxidrive已经提供了一个应该工作的脚本,但没有提供解释为什么你的代码失败了,他是如何解决问题的。
你有两个问题:
1)在循环中执行GOTO时,FOR循环立即中止。 GOTO目标标签放置在哪里并不重要 – GOTO总是终止一个循环。 Foxidrive对CALL的使用非常完美 – 一旦CALLed例程返回,循环将继续。
2)您尝试在代码块中设置变量,然后在同一个块内引用新值。 %VAR%
在解析语句时展开,像IF和FOR这样的复杂命令一次完整地被解析。 实际上,括号内的任何代码块都是一次性分析的。 因此, %ERRORLEVEL%
和%FILENAME%
的值将是常量 – 在块输入之前存在的值。
Endoro指出,解决这个问题的一个办法是使用延迟扩展。 延迟扩展必须通过使用setlocal enableDelayedExpansion
来启用,然后使用!VAR!
。 该值在执行时扩展而不是解析时间。 从命令提示符键入HELP SET
,获取有关延迟扩展的更多信息。
但是要小心,当使用FOR循环时,延迟扩展会导致它自己的问题,因为在FOR变量扩展之后发生延迟扩展:如果值包含!
%%x
将被损坏!
。 这个问题可以通过按照需要通过SETLOCAL和ENDLOCAL小心地切换延时扩展ON和OFF来解决。
Foxyrive的代码通过使用CALL避免了整个延迟扩展问题。 他的:NEXT例程不在FOR循环中,因此每次调用时都会重新命名所有的命令,所以不需要延迟扩展。
这可能工作 – 这是未经测试的:
@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
尝试这个:
@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="
如果你使用代码块( if
和for
( )
)和变量值变化,你必须启用delayed expansion
。 正如你所看到的,你不需要代码块。