3

如果我从命令提示符运行它,我有一个运行良好的批处理文件,但如果从任务计划程序调用或通过资源管理器运行它会引发错误。FOR 逻辑似乎发生了语法错误。

@echo off

del mic_car*.txt

ftp -i -s:car_ftp_script.txt

pause

for /F %%I in ('dir /b/os mic_car*.txt') do (
  echo %%I
  pause
  set tempfile=%%I
  if exist %tempfile% (
    del car_report.txt
    ren %tempfile% car_report.txt
  ) 
)

del mic_car*.txt
copy /y car_report.txt ..\car_report.txt

pause

如果我从资源管理器或任务计划程序运行它,我会看到文件正在通过 FTP 传输,然后是语法错误。如果我通过命令行运行它,我会看到正在处理的每个文件的回显,并且最大的文件被复制到更高级别的目录。

4

3 回答 3

3

即使从命令行,您的代码也无法正常工作。

您的问题是您在同一代码块中的设置tempfile和扩展。%tempfile%解析行时,值被扩展,FOR语句的所有行都被解析一次。因此,您的 IF 和 REN 语句看到的是在进入循环之前存在的值。

tempfile未定义时,您的代码会因语法错误而失败。展开后, IF 语句变为 invalid: if exist ( ...,因此报错。

您认为它可以从命令行运行的原因是因为您可能运行了一次代码并且它失败了,但是完成后,tempfile变量已设置,因此脚本在您下次运行时会显示运行正常。

通常我建议使用延迟扩展来启用循环内的设置和扩展变量。但是您根本没有任何理由使用tempfile- 只需直接使用 FOR 变量即可。

@echo off

del mic_car*.txt

ftp -i -s:car_ftp_script.txt

for /F %%I in ('dir /b/os mic_car*.txt') do (
  echo %%I
  if exist "%%I" (
    del car_report.txt
    ren "%%I" car_report.txt
  ) 
)

del mic_car*.txt
copy /y car_report.txt ..\car_report.txt

pause

实际上,我不明白为什么你需要 IF ,因为你的 FOR 循环只返回现有文件。并且所有 mic_car*.txt 文件都将被重命名为 car_report.txt(最后一个获胜),因此不需要您的最终 DEL 命令。

您可以使用 MOVE 将 DEL 和 REN 命令合并为一个命令

@echo off

del mic_car*.txt

ftp -i -s:car_ftp_script.txt

for /F %%I in ('dir /b/os mic_car*.txt') do (
  echo %%I
  move /y "%%I" car_report.txt >nul
)

copy /y car_report.txt ..\car_report.txt

pause
于 2013-07-02T16:36:47.090 回答
1

您使用的是什么版本的 Windows?

我已将脚本更改为使用从您的目录列表中提取的数据调用子例程。

@echo off

del mic_car*.txt

ftp -i -s:car_ftp_script.txt

pause

for /F %%I in ('dir /b/os mic_car*.txt') do call :blue %%I
goto exit

:blue
  echo -- processing %1 -------------
  pause
  set tempfile=%1
  if exist %tempfile% (
    del car_report.txt
    ren %tempfile% car_report.txt
    echo -- renamed %tempfile% to car_report.txt -------------
  ) 


del mic_car*.txt
copy /y car_report.txt ..\car_report.txt
echo -- finished %1 -------------
pause

goto :eof

:exit

Windows 资源管理器和调度程序之间的默认目录存在差异,因此,您应该考虑使用指向目标文件所在文件和目录的显式路径。例如del c:\carfiles\mi_car*.txt等。

于 2013-07-02T16:24:27.397 回答
0

这些行是您的错误的原因:

set tempfile=%%I
if exist %tempfile% (

%- 变量在解析时扩展,即解释器解析命令(在本例中为 for 循环)时。此时,循环变量没有值,因此%tempfile%为空,从而导致错误。

您需要启用延迟扩展并!在循环内使用 -variables。当循环变量包含实际值时,这些变量会在运行时展开。

setlocal EnableDelayedExpansion

for /F %%I in ('dir /b/os mic_car*.txt') do (
  echo %%I
  pause
  set tempfile=%%I
  if exist !tempfile! (
    del car_report.txt
    ren !tempfile! car_report.txt
  ) 
)
于 2013-07-02T16:32:49.513 回答