【问题标题】:Windows batch script - issue with moving files from a directory in a for loopWindows批处理脚本-从for循环中的目录移动文件的问题
【发布时间】:2017-09-17 15:07:49
【问题描述】:

我遇到了一个奇怪的问题,现在让我感到困惑 -

我正在运行的 Windows 脚本是一个包装脚本,它将遍历公共目录中的所有 csv 文件,并在我调用其中一个子进程之前将它们移动到处理文件夹。当输入文件夹中没有更多 csv 文件时,包装脚本应该终止。但是我收到一条消息说

'存在重复的文件名,或者文件 找不到。'

输入文件夹 \abcinc.lcl\utility\aaa 是一个空文件夹,其下没有其他文件或子文件夹。

以下 for 循环在没有文件时没有正常终止而是失败的任何原因?

for /F %%i in ('dir /b "\abcinc.lcl\utility\aaa*.csv"') 做 (

这里是完整的代码 sn-p 以及日志的输出 -

***************************************************************************
****    Wrapper Script                                                 ****
***************************************************************************

@echo off
Setlocal enabledelayedexpansion

for /F %%i in ('dir /b "\\abcinc.lcl\utility\aaa\*.csv"') do (
   echo Folder is NON empty
        move "\\abcinc.lcl\utility\aaa\*.csv" E:\abc\INFILES
    For %%a in (E:\abc\INFILES\*.csv) Do (
        PING 10.1.41.19 -n 5 >NUL
        Set "File=LOADIN.csv"
        Ren "%%a" "!File!"
        CALL "E:\abc\scripts\RUNALL.BAT"
        PING 10.1.41.19 -n 5 >NUL
        MOVE "E:\abc\INFILES\LOADIN.CSV" "E:\abc\INFILES\ARCHIVE\LOADIN - %DATE:/=-% %TIME::=-%.CSV"
    PING 10.2.23.49 -n 3 >NUL
        MOVE "\\abcinc.lcl\utility\aaa\OUTPUT\outfile.csv" "\\abcinc.lcl\utility\aaa\OUTPUT\ARCHIVE\outfile - %DATE:/=-% %TIME::=-%.CSV"

                             )

        )

EXIT

***********************************************************************
****    LOG OUTPUT                                                 ****
***********************************************************************


Folder is NON empty
\\abcinc.lcl\utility\aaa\File1.csv
\\abcinc.lcl\utility\aaa\File2.csv
        2 file(s) moved.

RunAll script ran fine.
        1 file(s) moved.
        1 file(s) moved.

RunAll script ran fine.
        1 file(s) moved.
        1 file(s) moved.

Folder is NON empty
A duplicate file name exists, or the file
cannot be found.

【问题讨论】:

  • 您的第一个move 命令将所有文件移动到infiles 文件夹,但如果有多个文件,for /f 会不断迭代初始dir 命令的输出。
  • 感谢@MCND,但我在括号内使用了整个 for 循环。我想知道当没有更多文件可以从输入文件夹中读取时,是否应该在结束括号之前使用显式退出以退出循环?但是如果整个 for /f 都包裹在 () 中,不明白为什么我必须通过显式退出?
  • 如果你有前任。文件夹中有3个文件,dir命令会生成三行输出。 for /f 遍历这三行,因此 do 子句中的代码将执行三次,无论您是否移动了文件并且它们不在源文件夹中。由于您没有使用%%i 值,因此如果dir 没有失败,您可以只用dir&& 条件执行运算符替换初始for /f,以执行其余代码。

标签: batch-file for-loop cmd


【解决方案1】:

FOR命令在后台命令进程中使用cmd.exe命令行执行:

dir /b "\\abcinc.lcl\utility\aaa\*.csv"

为处理 STDOUT 而编写的 DIR 的输出被 FOR 捕获。 DIR 在指定目录中没有 *.csv 文件时输出的可能错误消息被重定向到运行 FOR 的命令进程的控制台。

命令FOR在后台命令进程完成执行DIR后逐行处理捕获的输出。

因此,指定目录中的 *.csv 文件接下来会发生什么并不重要。 FOR 已在内存中逐行处理文件名列表。

这个带注释的批处理代码可能更适合您的任务:

@echo off
if not exist "\\abcinc.lcl\utility\aaa\*.csv" (
    echo Folder "\\abcinc.lcl\utility\aaa" contains no CSV files.
    goto :EOF
)

echo Folder "\\abcinc.lcl\utility\aaa" contains CSV files.
set "File=LOADIN.csv"

rem Move all CSV files from \\abcinc.lcl\utility\aaa to E:\abc\INFILES.
move /Y "\\abcinc.lcl\utility\aaa\*.csv" E:\abc\INFILES\ >nul

rem Process each CSV file in E:\abc\INFILES using subroutine ProcessFile.
for %%I in (E:\abc\INFILES\*.csv) do call :ProcessFile "%%I"

rem Exit processing of this batch file.
goto :EOF

:ProcessFile
rem Wait 4 seconds if a device with IP address 10.1.41.19 exists.
%SystemRoot%\System32\ping.exe 10.1.41.19 -n 5 >nul

rem Rename the current file temporarily.
ren %1 "%File%"

rem Call another batch file doing something.
call "E:\abc\scripts\RUNALL.BAT"

rem Wait again 4 seconds if a device with IP address 10.1.41.19 exists.
%SystemRoot%\System32\ping.exe 10.1.41.19 -n 5 >nul

rem Move the temporary file to input archive folder with
rem regional settings dependent date and time in new file name.
move "E:\abc\INFILES\%File%" "E:\abc\INFILES\ARCHIVE\LOADIN - %DATE:/=-% %TIME::=-%.CSV"

rem Wait again 2 seconds if a device with IP address 10.1.41.19 exists.
%SystemRoot%\System32\ping.exe 10.2.23.49 -n 3 >nul

rem Move output CSV file to output archive folder again with
rem regional settings dependent date and time in new file name.
move "\\abcinc.lcl\utility\aaa\OUTPUT\outfile.csv" "\\abcinc.lcl\utility\aaa\OUTPUT\ARCHIVE\outfile - %DATE:/=-% %TIME::=-%.CSV"

rem Exit the subroutine ProcessFile.
goto :EOF

子程序的使用使得处理所有 CSV 文件而不使用延迟扩展成为可能。

要了解所使用的命令及其工作原理,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。

  • call /?
  • dir /?
  • echo /?
  • for /?
  • goto /?
  • if /?
  • move /?
  • ping /?
  • set /?

另请阅读有关 Using Command Redirection Operators 的 Microsoft 文章。

【讨论】:

  • 感谢@Mofi 的详细解释以及您重写例程的时间和精力。非常感激。我正在阅读命令帮助页面,并且有很多关于它们如何在后台由 cmd.exe 处理的信息。再次感谢!!
猜你喜欢
  • 1970-01-01
  • 2013-10-01
  • 2016-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-13
  • 1970-01-01
  • 2017-02-03
相关资源
最近更新 更多