Brendon
Brendon

Reputation: 57

Windows batch script - issue with moving files from a directory in a for loop

I have come across an strange issue that puzzles me at the moment -

The windows script I am running is a wrapper script that will loop through all the csv files from a public directory and will move them to a processing folder before I call one of the sub-processes. The wrapper script is supposed to terminate when there is no more csv files left in the input folder. However I am getting a message saying

'A duplicate file name exists, or the file cannot be found.'

The input folder \abcinc.lcl\utility\aaa sits as an empty folder with no other files or sub-folders under it.

Any reasons why the following for loop is not terminating normally upon no files and failing instead?

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

Here is the full code snippet along with the output from the log -

***************************************************************************
****    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.

Upvotes: 1

Views: 2012

Answers (1)

Mofi
Mofi

Reputation: 49097

The command FOR executes in a background command process using cmd.exe the command line:

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

The output of DIR written to handle STDOUT is captured by FOR. A possible error message output by DIR on no *.csv file in specified directory is redirected to console of command process running FOR.

Command FOR processes line by line the captured output after the background command process finished with execution of DIR.

For that reason it does not matter what happens next with the *.csv files in the specified directory. FOR has already the list of file names to process line by line in memory.

This commented batch code could be better for your task:

@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

The usage of a subroutine makes it possible to process all CSV files without usage of delayed expansion.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

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

Read also the Microsoft article about Using Command Redirection Operators.

Upvotes: 1

Related Questions