我正在尝试编写一个批处理文件,以便在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=
答案 0 :(得分:4)
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,可以解决这个问题。
Foxidrive的代码通过使用CALL避免了整个延迟扩展问题。他的:NEXT例程不在FOR循环中,因此每次调用时都会重新解析所有命令,因此不需要延迟扩展。
答案 1 :(得分: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
答案 2 :(得分: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="
如果您使用代码块(if
和for
与( )
)和变量值变量,则必须启用delayed expansion
。您可以看到,此代码中不需要代码块。