Siwap
Siwap

Reputation: 63

Duplicate Files within original folder

I have this batch file that duplicates all the .jpg's in my folders and subfolders and renames them with -Copy on the end. Problem is I need the duplicate jpg's to be created in the same folder as the original jpg's, the script I have copy's them to the directory that the batch file is in. Here's the file:

for /R %%f in (*.jpg) do copy "%%~f" "%%~nf - Copy%%~xf"

What happens when I run the script at the moment - You'll see 1-copy.jpg and 2-copy.jpg are created in the same folder as the batch file.

Images/
├── batchfile.bat
│   1-Copy.jpg
│   2-Copy.jpg
├── Folder1/
│   ├── 1.jpg
├── Folder2/
│   ├── 2.jpg

What I'm trying to do is keep 1-copy.jpg and 2-copy.jpg in the same folder as the original jpg's. Like below.

Images/
├── batchfile.bat
├── Folder1/
│   ├── 1.jpg
│   ├── 1-Copy.jpg
├── Folder2/
│   ├── 2.jpg
│   ├── 2-Copy.jpg

Upvotes: 1

Views: 1164

Answers (1)

Mofi
Mofi

Reputation: 49086

The solution seems to be quite simple: reference for target file the drive and path of source file. But it is not so simple because it should be avoided that at * - Copy.jpg is copied again and again with appending  - Copy to file name on each execution of the batch file. So it is necessary to filter out all JPEG file names ending already with that string.

It is also better here to use I instead of f as loop variable although f would be also possible just to avoid a confusion with modifier f (full qualified file/folder name).

for /F "delims=" %%I in ('dir *.jpg /A-D-H /B /S 2^>nul ^| %SystemRoot%\System32\findstr.exe /E /I /L /V /C:" - Copy.jpg"') do copy /B /Y "%%I" "%%~dpnI - Copy%%~xI"

FOR executes in a separate command process started with cmd.exe /C in background the command line:

dir *.jpg /A-D-H /B /S 2>nul | C:\Windows\System32\findstr.exe /E /I /L /V /C:" - Copy.jpg"

Read the Microsoft article about Using Command Redirection Operators for an explanation of | and 2>nul. The redirection operators | and > must be escaped with caret character ^ on FOR command line to be interpreted as literal characters when Windows command interpreter processes this command line before executing command FOR which executes the embedded command line with using a separate command process started in background.

DIR searches for

  • non-hidden *.jpg files because of /A-D-H (attribute not directory and not hidden)
  • in current directory and all subdirectories because of /S
  • and outputs in bare format because of option /B just file name with file extension with full path because of /S of all found files.

This output written by DIR to handle STDOUT is redirected to handle STDIN of command FINDSTR which processes the list line by line. FINDSTR searches

  • at end of each line because of /E
  • case-insensitive because of /I
  • and literally because of /L (would not be really needed in this case)
  • for the string  - Copy.jpg and
  • outputs inverted result because of /V which means all lines not ending with that string to handle STDOUT.

FOR captures everything written to STDOUT and processes it line by line. Empty lines and lines starting with a semicolon would be skipped by FOR, but such lines do not exist in this case. FOR would split up a line on spaces/tabs and would assign just first substring to loop variable I. This string splitting behavior is disabled by using option "delims" which defines an empty list of delimiters.

The source file can be specified here with just "%%I" because of DIR outputs the names of found JPEG files always with full path not enclosed in double quotes. So there is never the requirement to remove surrounding double quotes.

The batch file with the single command line works also on FAT32 and ExFAT drives because of processing a captured list of file names instead of processing directly the *.jpg file entries in file allocation table which changes after each JPEG file copy.

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.

  • copy /?
  • dir /?
  • echo /?
  • findstr /?
  • for /?

Upvotes: 2

Related Questions