Rename specific files within a launch directory to the name of the directory while retaining extensions

52 Views Asked by At

I'm a novice hobby programmer and I am trying to rename files within a directory for DVD/BD backups and appropriate folder structure for streaming players. To reduce the tedium of this, I would like to ideally generate a script I can launch from the R-click menu on Windows 10 to be launched within that directory itself.

The goal would be to rename ripped files that have been placed in directories and downloaded images with a random name as follows:

C:\User\Me\Videos\Star Trek
-- Star Trek (DVD) Disc 1
   -- ABCST-disc-1.iso
   -- randomname1.jpg
   -- folder.txt
-- Star Trek (DVD) Disc 2
   -- ABCST-disc-2.iso
   -- randomname2.png
   -- folder.txt
-- Star Trek (BD) Disc 1
   -- ABCST-bd-disc-1 (folder structure)
      -- BDMV (and subfolders)
      -- CERTIFICATE (and subfolders)
   -- randomname3.png
   -- folder.txt

and trying to convert them into:

C:\User\Me\Videos\Star Trek
-- Star Trek (DVD) Disc 1
   -- Star Trek (DVD) Disc 1.iso
   -- Star Trek (DVD) Disc 1.jpg
   -- folder.txt
-- Star Trek (DVD) Disc 2
   -- Star Trek (DVD) Disc 2.iso
   -- Star Trek (DVD) Disc 2.png
   -- folder.txt
-- Star Trek (BD) Disc 1
   -- Star Trek (BD) Disc 1 (folder structure)
      -- BDMV (and subfolders)
      -- CERTIFICATE (and subfolders)
   -- Star Trek (BD) Disc 1.png
   -- folder.txt

I have gotten so far as to generate this code, however the caveats are that the filepath is specific for the root directory folder and therefore there has to be a batch file in each subdirectory which is inconvenient for every series and disc.

I would like to launch the script from the root directory, in this case "C:\User\Me\Videos\Star Trek") and convert the various subdirectories (Star Trek (DVD) Disc 1, Star Trek (DVD) Disc 2, etc.) such that specified filetypes (.iso, .mkv, .png, .jpg) is changed to the direct subdirectory name with retained file extensions.

The batch file code I generated is as follows:

@echo off
except (folder.txt)
for /d %%a in ("C:\User\Me\Videos\Star Trek\Star Trek (DVD) Disc 1") do ren "%%~fa\*.png" "%%~na.*"
for /d %%a in ("C:\User\Me\Videos\Star Trek\Star Trek (DVD) Disc 1") do ren "%%~fa\*.jpg" "%%~na.*"
for /d %%a in ("C:\User\Me\Videos\Star Trek\Star Trek (DVD) Disc 1") do ren "%%~fa\*.iso" "%%~na.*"
for /d %%a in ("C:\User\Me\Videos\Star Trek\Star Trek (DVD) Disc 1") do ren "%%~fa\*.mkv" "%%~na.*"

Therefore my questions are:

  1. Is there a way to alter the batch file so that it identifies files in whichever directory it is launched in (so as to replace the "C:\User\Me\Videos\Star Trek\Star Trek (DVD) Disc 1" below?
for /d %%a in ("C:\User\Me\Videos\Star Trek\Star Trek (DVD) Disc 1") do ren "%%~fa\*.png" "%%~na.*"`
  1. Group together the filetypes I'm interested in converting (.iso, .mkv, .png, .jpg) so that it is not redundant pieces of code?

  2. Maintain exception so that "folder.txt" is untouched in the process, so far my testing shows that the "except" sub command seems to work here, but just a consideration for altered code.

  3. optional I'm working on one thing at a time (renaming video files/isos/mkvs), however some BD rips come as BDMV folders. Ideally I would like these to be named the same as their parent folder.

1

There are 1 best solutions below

0
Mofi On

The file renaming task can be done with following single command line:

@for /F "delims=" %%I in ('dir "%USERPROFILE%\Videos\*.iso" "%USERPROFILE%\Videos\*.jpg" "%USERPROFILE%\Videos\*.mkv" "%USERPROFILE%\Videos\*.png" /A-D /B /S 2^>nul') do @for %%J in ("%%~dpI.") do @if /I not "%%~nI" == "%%~nxJ" ren "%%I" "%%~nxJ%%~xI"

The first FOR executes in background one more command process started with %ComSpec% /c and the command line inside ' appended as additional arguments.

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

The additional command process runs its internal command DIR to search once

  • in the multiple times specified directory %USERPROFILE%\Videos
  • and in all its subdirectories because of option /S
  • for just files because of option /A-D (attribute not directory)
  • of which long or short file names matches *.iso or *.jpg or *.mkv or *.png
  • and outputs in bare format just the found file names because of option /B
  • with full path because of option /S.

DIR is so smart that it detects that all wildcard patterns search in the same directory and traverses through the entire directory tree only once with all four wildcard patterns.

The output list of file names to handle STDOUT of the background command process is captured by the Windows Command Processor which is processing the batch file and loaded into its memory. The behavior of getting first all file names to possibly rename loaded into memory is highly recommended as the command REN used inside the loop results in modification of the file system entries.

FOR with option /F processes the list of captured file names after cmd.exe started in background closed itself after finishing the execution of its internal command DIR. Empty lines would be ignored by FOR but DIR with the used options does not output any empty line.

FOR would split up by default each non-empty line into substrings using normal space and horizontal tab as string delimiters. That line splitting behavior is not wanted here as the file names with full path contain space characters. The option delims= defines an empty list of delimiters resulting in turning off the line splitting behavior. Each full file name is assigned for that reason to the loop variable I. FOR would ignore a line if its first substring (here the entire line) would begin with a semicolon. That is not possible in this case because of DIR outputs the file names with full path because of option /S.

The inner FOR processes just the full path of the current file which always ends with a backslash. There is appended . which means the current directory, i.e. the directory of the file currently processed. The usage of . is necessary to get next with %%~nxJ just the directory name of the file without the path, i.e. %USERPROFILE%Videos\Star Trek\Star Trek (DVD) Disc 1\ as referenced with %%~dpI becomes %USERPROFILE%Videos\Star Trek\Star Trek (DVD) Disc 1\. with a dot at the end which expands to %USERPROFILE%Videos\Star Trek\Star Trek (DVD) Disc 1 without a backslash at the end resulting in usage of %%~nxJ in the string Star Trek (DVD) Disc 1.

The currently processed file name without path and without file extension is now compared case-insensitive with the name of the directory in which this file exists. The command REN is executed for renaming the file to name of the directory if the two strings are not equal. That file rename operation causes a file system change which does not matter as all file names are already loaded into memory of cmd.exe processing the batch file.

The three @ should be removed if the batch file has as first line @echo off for turning off completely the command echo mode which is turned off for a single command execution also with @.

The optional requirement is not implemented in the command line posted at top. It could be done in the same command line, but it would be perhaps better to use one more FOR command line which explicitly processes next only BDMV.iso, BDMV.jpg, BDMV.mkv and BDMV.png.

@for /F "delims=" %%I in ('dir "%USERPROFILE%\Videos\BDMV.iso" "%USERPROFILE%\Videos\BDMV.jpg" "%USERPROFILE%\Videos\BDMV.mkv" "%USERPROFILE%\Videos\BDMV.png" /A-D /B /S 2^>nul') do @for %%J in ("%%~dpI..") do @ren "%%I" "%%~nxJ%%~xI"

It would be also possible using the following command line to move up the files in subfolder BDMV with changing the file name and delete the folder BDMV on being finally empty.

@for /F "delims=" %%I in ('dir "%USERPROFILE%\Videos\BDMV.iso" "%USERPROFILE%\Videos\BDMV.jpg" "%USERPROFILE%\Videos\BDMV.mkv" "%USERPROFILE%\Videos\BDMV.png" /A-D /B /S 2^>nul') do @for %%J in ("%%~dpI..") do @move /Y "%%I" "%%~fJ\%%~nxJ%%~xI" >nul & rd "%%~dpI" 2>nul