0

I have a Windows CMD script that has a bug. The script is supposed to match the first 8 digits (the date) of a file with a directory titled with the same first 8 digits (the date). If successful, the file is moved into that directory & placed in a subfolder (called 'portfolio'). However, the error File not Found is returned.

file: 20230202_example.jpg
directory: 20230202_winter-holiday/portfolio

...the CMD file:

@echo off

for /f "delims=" %%a in ('dir /b /a-d') do (
  set "filename=%%a"
  set "first8=!filename:~0,8!"
  for /f "delims=" %%b in ('dir /b /a-d *%first8%*') do (
    if /i "!filename!" neq "%%b" ( 
    move "!filename!" "%%b\portfolio\!filename!"
    )
  )
)

If I interrogate the directory in Command Prompt:

dir /b /a-d

...I get a full list of the files contained. When the script is run from Command Prompt, for each file contained I get:

File Not Found
  • 1
    Yo need a line `setlocal enabledelayedexpansion` directly after the `@echo off` line. This invokes `delayedexpansion` which allows access to the run-time value of variables via `!var!`. WIthout the `setlocal` line, `!` is an ordinary character, so you are looking for a filename containing `!` characters (and others). You also need to use `!first8!`, not `%first8%` because you are varying the value of `first8` within the loop Beware of the [delayed expansion trap](https://stackoverflow.com/a/30284028/2128947) – Magoo Feb 02 '23 at 20:52

1 Answers1

0

Based upon your target file and directory names, you could probably do it without defining variables and therefore the need to delay variable expansion.

Example:

@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
For /F "Delims=" %%G In ('Dir "????????_*" /A:-D /B 2^>NUL
 ^| %SystemRoot%\System32\findstr.exe /R /C:"^202[0123]1[012][12][0123456789]_."
 /C:"^19[789][0123456789]0[123456789]0[123456789]_."
 /C:"^19[789][0123456789]0[123456789][12][0123456789]_."
 /C:"^19[789][0123456789]0[123456789]3[01]_." /C:"^202[0123]0[123456789]3[01]_."
 /C:"^19[789][0123456789]1[012]0[123456789]_."
 /C:"^19[789][0123456789]1[012][12][0123456789]_."
 /C:"^19[789][0123456789]1[012]3[01]_." /C:"^20[01][0123456789]1[012]3[01]_."
 /C:"^20[01][0123456789]0[123456789]0[123456789]_." /C:"^202[0123]1[012]3[01]_."
 /C:"^20[01][0123456789]0[123456789][12][0123456789]_."
 /C:"^20[01][0123456789]0[123456789]3[01]_."
 /C:"^20[01][0123456789]1[012]0[123456789]_."
 /C:"^20[01][0123456789]1[012][12][0123456789]_."
 /C:"^202[0123]0[123456789]0[123456789]_." /C:"^202[0123]1[012]0[123456789]_."
 /C:"^202[0123]0[123456789][12][0123456789]_."
 ') Do For /F "Delims=_" %%H In ("%%~nG") Do For /F "Delims=" %%I In ('
 Dir "%%H_*" /A:D /B 2^>NUL'
) Do %SystemRoot%\System32\Robocopy.exe . "%%I\portfolio" "%%G" /Mov 1>NUL 2>&1

I decided to use a little more accuracy in the dates, (it's not perfect because it has no knowlege of how many days are in each month of any year, but should cover dates between 19700101 and 20231231). If you don't want that, you could simplify it by just removing lines 4 through 17:

@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
For /F "Delims=" %%G In ('Dir "????????_*" /A:-D /B 2^>NUL
 ') Do For /F "Delims=_" %%H In ("%%~nG") Do For /F "Delims=" %%I In ('
 Dir "%%H_*" /A:D /B 2^>NUL'
) Do %SystemRoot%\System32\Robocopy.exe . "%%I\portfolio" "%%G" /Mov 1>NUL 2>&1
Compo
  • 36,585
  • 5
  • 27
  • 39