-1

I want to find file list PATH1 and overwrite it if there is a file with the same name on PATH2.

@echo off

SET PATH1="FIND_PATH"
SET PATH2="OVERWRITE_PATH"

for /f "delims=" %%A in ('dir /b %PATH1%') do (
    dir /s /b /r %PATH2% | find /i "%%A" > list.txt
    SET /p PATH3<=list.txt
    move %PATH1%%%A %PATH3%
)

At line 7, If possible, it would be nice to store it in a variable without going through list.txt in the middle.

I perform "ECHO %PATH3%" outside the for syntax, the last saved item is output. but I perform "ECHO %PATH3%" inside the do syntax, Outputs an error.

how can I do.

thx.

TyNano
  • 1
  • 1
  • 1
    Does this answer your question? [Variables are not behaving as expected](https://stackoverflow.com/questions/30282784/variables-are-not-behaving-as-expected) Specifically, add `setlocal enabledelayedexpansion` under the `@echo off` and use `!PATH3!` instead of `%PATH3%`. – SomethingDark Dec 01 '22 at 06:06

1 Answers1

0

Here's my analysis of your code:

for /f "delims=" %%A in ('dir /b %PATH1%') do (
  rem %%A contains filename + extension of each file AND DIRECTORY in path1
    dir /s /b /r %PATH2% | find /i "%%A" > list.txt
  rem LIST.txt contains full pathnames of all filenames AND DIRECTORIES
  rem where "%%A" forms part of the full pathname
    SET /p PATH3<=list.txt
  rem PATH3 contains the first line of list.txt
    move %PATH1%%%A %PATH3%
  rem move `path1%%A` (a file or directoryname - but without the `\` separator)
  rem to the first (probably filename) found
)

Comment : first time in using batch for the last 40 years that I've ever seen the /r swich used in a dir statement...

So - we have to make some reasonable assumptions as to the intent of this code.

Tip: Use set "var=value" for setting string values - this avoids problems caused by trailing spaces. Don't assign " or a terminal backslash or Space. Build pathnames from the elements - counterintuitively, it is likely to make the process easier. If the syntax set var="value" is used, then the quotes become part of the value assigned.

@echo off

SET "PATH1=FIND_PATH"
SET "PATH2=OVERWRITE_PATH"

for /f "delims=" %%b in ('dir /b /a-d "%PATH1%"') do (
  for /f "delims=" %%u in ('dir /s /b /a-d /r "%PATH2%\%%b" 2^>nul') do (
    ECHO move "%PATH1%\%%A" "%%u"
  )
)

[1] Change to better set syntax
[2] Prefer to avoid ADFNPSTXZ (in either case) as metavariables (loop-control variables) as ADFNPSTXZ are metavariable-modifiers which can lead to difficult-to-find bugs (See for/f from the prompt for documentation)
[3] Include /a-d to exclude directory names from dir lists
[4] Include %%b in the filemask for the inner for to search for that exact name only in the destination directory-tree
[5] The 2^>nul suppresses an error message should no files be found in the destination-tree matching the filename. The caret (^) is required to tell cmd that the > is part of the dir command, not the for
[6] Append the filename found (%%b) to the source directoryname with required separator
[7] %%u will contain the full pathnames of the matching files in the destination directory-tree
[8] The resultant command is merely echoed for verification. After verification, remove the echo keyword to actually execute the move.

Untested

Always verify against a test directory before applying to real data.

The effect would be to find all of the filenames in the source directory and move it over all matching filenames in the destination directory tree.

LOGICAL FLAW
a "move" command would move a file a.txt over the first a.txt in the destination-tree. Then the source file no longer exists (as it's been moved) so if a second a.txt is located in the destination-tree, then the move will fail.

Consider this further modification:

@echo off

SET "PATH1=FIND_PATH"
SET "PATH2=OVERWRITE_PATH"

for /f "delims=" %%b in ('dir /b /a-d "%PATH1%"') do (
  set "moved="
  for /f "delims=" %%u in ('dir /s /b /a-d /r "%PATH2%\%%b" 2^>nul') do (
    set "moved=y"
    ECHO COPY "%PATH1%\%%A" "%%u"
  )
  if defined moved (
   ECHO del "%PATH1%\%%A"
  ) else (
   ECHO "%PATH1%\%%A" - no matches in tree "%PATH2%" found
   ECHO MOVE "%PATH1%\%%A" "%PATH2%"
  )
)

This change sets moved to nothing for each source file found, then sets it to y if any matching filename is found n the destination tree.

If the file has been copied, then delete the source file, otherwise complain and move it to the destination-tree-root.

Magoo
  • 77,302
  • 8
  • 62
  • 84