0

I'm having some difficulty getting my head around variables in my batch file for loops. When I think I have it down, I find an example where it doesn't work as I expect and I feel I've been going in circles with this...

I've written my entire bulk of code incase it makes a difference, basically I have an archive folder with many subfolders and I want to check if my upload data (which will be moved to the archive folder at the end of the script - to be written when I get this part working) has already been processed. If so, move to a Duplicates folder with the date:

 @echo off

 for /F "usebackq tokens=1,2 delims==" %%i in (`wmic os get LocalDateTime /VALUE 2^>NUL`) do if '.%%i.'=='.LocalDateTime.' set localDT=%%j
 set localYYYY=%localDT:~0,4%
 set localMM=%localDT:~4,2%
 set localDD=%localDT:~6,2%
 set localDate=%localYYYY%-%localMM%-%localDD%
 set localTime=%localDT:~8,2%:%localDT:~10,2%

 for %%f in ("C:\Test\837Store\*.837") DO if exist /R "C:\Test\Archive\%%~nxf" (
     set VariableTemp=%%~nxf
     echo %VariableTemp%
     IF NOT EXIST "C:\Test\Archive\Duplicates" mkdir "C:\Test\Archive\Duplicates"
     IF NOT EXIST "C:\Test\Archive\Duplicates\%localYYYY%" mkdir "C:\Test\Archive\Duplicates\%localYYYY%"
     IF NOT EXIST "C:\Test\Archive\Duplicates\%localYYYY%\%localMM%" mkdir "C:\Test\Archive\Duplicates\%localYYYY%\%localMM%"
     copy "%%~nxf" "C:\Test\Archive\Duplicates\%localYYYY%\%localMM%"
     echo %localDate% %localTime%        Duplicate claims file: %%~dpnxf File moved to archive     >> "C:\Test\Log\Error.log"
 )
 pause

My problem is, the variable %%f doesn't seem to be set through the loop. The mkdir commands are run, but I get a "file not found" error when we get to the copy. To try and see what was happening, I included the VariableTemp and set as per the code, expecting to see the name and extension of the file. Instead, my echo is printing "%~nxf"

Can anyone help me understand how these variables are working? Why am I not seeing the file names from my 837Store?

Just for additional information, I have the following 2 files in C:\Test\837Store:

1.837 2.837

I have the same 2 files in C:\Test\Archive\2013\08 and so would expect them to be moved from 837Store to the relevant Duplicates folder.

Thanks.

3
  • Endoro has the problem nailed, but a couple of comments: The fact that you saw "%~nxf" as the value of VariableTemp indicates that a previous run had set VariableTemp to this value. Unlike most languages, batch inherits variables from prior programs run in the same cmd session. Any change made by a batch program remains in place until specifically changed again - UNLESS the change is made between a setlocal and an endlocal (or end-of-file/program) at which time the environment is restored to its state when the setlocal was executed. Commented Aug 7, 2013 at 4:23
  • Next issue is a matter of style. The IF NOT EXIST "dirname" certainly works, but md "dirname" 2>nul will make a directory if it does not already exist, the 2>nul dumps the 'it already exists' message. There's little point in putting this INSIDE the loop, since the target directory(s) names don't change within the loop. The md/mkdir (they're synonymous) should be moved outside of the loop - before the FOR - done once, not (potentially) many times. Finally, IF EXIST /R is not nominally valid syntax. What is it intended to do? Commented Aug 7, 2013 at 4:32
  • Thanks for the tips! The reason I added the /R is because without it the script doesn't seem to iterate through the subfolders - the "Duplicates" folder is created with the /R, but not if I remove it. To be honest, I've built this more using trial-and-error as opposed to proper understanding so these answers are fantastic. Thanks! Commented Aug 7, 2013 at 14:13

1 Answer 1

1
@ECHO OFF
SETLOCAL

for /F "usebackq tokens=1,2 delims==" %%i in (`wmic os get LocalDateTime /VALUE 2^>NUL`) do if '.%%i.'=='.LocalDateTime.' set localDT=%%j
set localYYYY=%localDT:~0,4%
set localMM=%localDT:~4,2%
set localDD=%localDT:~6,2%
set localDate=%localYYYY%-%localMM%-%localDD%
set localTime=%localDT:~8,2%:%localDT:~10,2%

mkdir "U:\Test\Archive\Duplicates\%localYYYY%\%localMM%" 2>nul


for /R U:\Test\837Store %%f in (*.837) DO ECHO processing %%~ff&if exist "U:\Test\Archive\%%~nxf" (
 IF EXIST "u:\Test\Archive\Duplicates\%localYYYY%\%localMM%\%%~nxf" (
  echo %localDate% %localTime%        Duplicate claims file: %%~dpnxf File ALREADY DUPLICATED   >> "u:\Error.log"
 ) ELSE (
  MOVE "%%~ff" "u:\Test\Archive\Duplicates\%localYYYY%\%localMM%"
  echo %localDate% %localTime%        Duplicate claims file: %%~dpnxf File moved to archive     >> "u:\Error.log"
 )
)
rmdir "U:\Test\Archive\Duplicates\%localYYYY%\%localMM%" 2>nul
rmdir "U:\Test\Archive\Duplicates\%localYYYY%" 2>nul
rmdir "U:\Test\Archive\Duplicates" 2>nul
GOTO :EOF

Here's my interpretation.

I've used my RAMdrive for testing, so the driveletter will need to be changed, and the error-log location also.

I've added an extra test for a duplicate-already-exists - just reports that situation.

I've changed your COPY to a MOVE to match your narrative. Either way, a >nul appended to the command should suppress the '1 file copied/moved' message if you want it suppressed.

The MD/MKDIR will create any necessary subdirectory above the target.

The three 'rmdir/RD`s at the end are designed to remove any empty subdirectories with the target names.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks again for the help Peter! Unfortunately I'm still running into the same "cannot find the specified file" error. The Duplicates folders are created and then deleted as the .837 files are not copied. In fact, the error.log file is printing with the line "Duplicate claims file: %~dpnxf File moved to archive" - to me it's as if the variable has not been set as per my original question, otherwise we should be getting the file path and name in there, right? Is it possible that there might be some security or permission issue underlying this?
Just an additional comment, the variable works on the 1st line of the for loop, just doesn't seem to inside it for some reason. The ouput I get in the terminal is: "processing C:\Test\837Store\1.837" "processing C:\Test\837Store\2.837" "The system cannot find the file specified"
Ouch! That's very puzzling. The code I've provided was pasted directly from my test setup, where it appeared to work perfectly. Perhaps a few fundamental issues - batch is somewhat sensitive to layout and the position of spaces. Editors like NOTEPAD sometimes attempt to reformat batches in a strange way. Best to copy-paste into a proper editor like editplus. Batch is largely case-insensitive MAJOR EXCEPTION is the for loop metavariable %%f (in your case). Finally, are you sure that you have correctly modified all of the u: instances?
BUT none of this should render the %~dpnxf text you report in the logfile - so, bit of a mystery. Actually, the ECHO processing %%~ff was a piece of leftover testing code I omitted to excise. You may get a better idea of what precisely is happening by adding @echo on on a new line just before the FOR/R line and 'pause` on a new line just before the last closing-parenthesis line. This should show explicitly what the procedure is doing.
Thanks for your assistance @Peter. I'm still not getting the desired results, but I am seeing somethinb very odd. I've carefully checked for spacing issues in linkeditplus and all u: instances are cleared. When putting the echo and pause commands as you suggest, I've seen something very weird: processing 1.837, processing 2.837 IF EXIST... ELSE... - I'd expect to see Processing 1.837, IF EXIST... ELSE... Processing 2.837, IF EXIST... ELSE... It's as if the for isn't looping outside of the top line, although my parenthesis is correctly set - any idea why?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.