Batch Create a Folder Based on Filename, and Move

2019-01-22 22:29发布

For years I've always had all my movies dumped into one folder, along with all of their extras. I've realized now after several frustrations keeping a backup of nfo and art would save me hours of life, and keep the database more usable when adding a new Kodi setup (TV, Tablet, Laptop, etc...). So I'm trying to batch create a folder based on the filename of the movie, and move multiple related files to the created folder.

To be clear, I want to make a folder name of the movie and have all the related files go into that folder. The movie filesnames' format can change because they don't all have the same info, i.e. Director's cut, unedit, ultimate edition, which are in brakets []. The main movie name would in all cases be the smallest filename, and I'd never want the folder to be named with a file that contained "[Extra]" in the filename. Generally speaking the format is "Movie (year) [extra info] ... [extra info] small description here" for the non-movie videos.

The best I've come up with is:

for %%i in (*) do md "%%~ni" && move "%%~i" "%%~ni"

The problem right now is I'm creating a folder for every file and moving all the files to the respective folders but related content is now in different folders and things with the exact same filename is getting left in the main folder.

An example of what I'm trying to accomplish:

  • \'71 [Extra] sup stuff.mp4
  • \'71.mkv
  • \3 Geezers! (2013)-fanart.jpg
  • \3 Geezers! (2013)-poster.jpg
  • \3 Geezers! (2013).mp4
  • \3 Geezers! (2013).nfo
  • \3 Women (1977)-fanart.jpg
  • \3 Women (1977)-poster.jpg
  • \3 Women (1977).mp4
  • \3 Women (1977).nfo
  • \12 Years A Slave (2013).mp4
  • \13 (2010).mp4
  • \A Case Of You (2013).avi
  • \A Single Shot (2013).mp4
  • \Abre Los Ojos (1997) [Open Your Eyes] [SPA] [Extra] Test.mp4
  • \Abre Los Ojos (1997) [Open Your Eyes] [SPA].avi
  • \Abre Los Ojos (1997) [Open Your Eyes] [SPA].srt
  • \G.B.F. (2013).mp4
  • \G.I. Joe Retaliation (2013).mkv
  • \G.I. Joe Retaliation (2013).srt
  • \Test Movie (1977) [Comm].mp4

To:

  • \'71\'71 [Extra] sup stuff.mp4
  • \'71\'71.mkv
  • \3 Geezers! (2013)\3 Geezers! (2013)-fanart.jpg
  • \3 Geezers! (2013)\3 Geezers! (2013)-poster.jpg
  • \3 Geezers! (2013)\3 Geezers! (2013).mp4
  • \3 Geezers! (2013)\3 Geezers! (2013).nfo
  • \3 Women (1977)\3 Women (1977)-fanart.jpg
  • \3 Women (1977)\3 Women (1977)-poster.jpg
  • \3 Women (1977)\3 Women (1977).mp4
  • \3 Women (1977)\3 Women (1977).nfo
  • \12 Years A Slave (2013)\12 Years A Slave (2013).mp4
  • \13 (2010)\13 (2010).mp4
  • \A Case Of You (2013)\A Case Of You (2013).avi
  • \A Single Shot (2013)\A Single Shot (2013).mp4
  • \Abre Los Ojos (1997) [Open Your Eyes] [SPA]\Abre Los Ojos (1997) [Open Your Eyes] [SPA] [Extra] Test.mp4
  • \Abre Los Ojos (1997) [Open Your Eyes] [SPA]\Abre Los Ojos (1997) [Open Your Eyes] [SPA].avi
  • \Abre Los Ojos (1997) [Open Your Eyes] [SPA]\Abre Los Ojos (1997) [Open Your Eyes] [SPA].srt
  • \G.B.F. (2013)\G.B.F. (2013).mp4
  • \G.I. Joe Retaliation (2013)\G.I. Joe Retaliation (2013).mkv
  • \G.I. Joe Retaliation (2013)\G.I. Joe Retaliation (2013).srt
  • \Test Movie (1977) [Comm]\Test Movie (1977) [Comm].mp4

Can anyone help me with this batch code? Not all the files names are Movie (Year) [Comm] ..., some are just Movie, or Movie [Comm].

In summary: I want to create a folder based on a movie, ie any file with a specific video extension, such as mp4, mkv, avi, etc... that also doesn't contain: [Extra]; then move all associated files into that folder.

I've gone through these sources:

  1. Batch create folders based on part of file name and move files into that folder
  2. Batch Created Folder By Filename Part and Move
  3. Batch create folders based on series of files and move to subdirectory
  4. Batch script to create folders based on filenames
  5. create folders based on a file name and move those files into that folder
  6. https://superuser.com/questions/762113/cmd-command-to-create-folder-for-each-file-and-move-file-into-folder
  7. Batch script that moves each file in a folder into their own folders named after the file?
  8. Batch command move png files to folders same name files and folders
  9. Batch command to check for partial filename then move
  10. An A-Z Index of the Windows CMD command line: http://ss64.com/nt/

4条回答
不美不萌又怎样
2楼-- · 2019-01-22 23:02

Although your description is ample, you forgot to give some specific details; for example: starts all file names with the "Movie (year)" part? If so, then this Batch file do what you want:

EDIT: Ops, I misread the requirements! This version works correctly:

@echo off
setlocal

set "basename=."
for /F "tokens=1* delims=." %%a in ('dir /B /A-D ^| sort /R') do (
   set "filename=%%a"
   setlocal EnableDelayedExpansion
   for /F "delims=" %%c in ("!basename!") do if "!filename:%%c=!" equ "!filename!" (
      set "basename=!filename!"
      md "!basename!"
   )
   move "!filename!.%%b" "!basename!"
   for /F "delims=" %%c in ("!basename!") do (
      endlocal
      set "basename=%%c
   )
)
查看更多
Rolldiameter
3楼-- · 2019-01-22 23:06

It's not easy to do this, because you'd have to sort the file names. You can specify a sort order using dir, but it won't have the shortest names first. For instance foo.wmv is alphabetically behind foo subtitles.srt, because space comes before dot.

So as a work-around, maybe you could have a list of 'known extensions' which contain the basic movie names, and then move all the files that share the base name with them. The following script does just that. It lists all files with avi, mp4 and mkv extensions, but maybe you would have to start with nfo, which may be available for many movies. The script uses the file names of those files to make directories for and find related files. it seems to do the trick, but please make a backup before you use it. :)

The assumption in this script is that the file with the known extension also has the shortest name. If there are other files that have shorter names (or otherwise not matching) then they won't be moved to that folder.

The script isn't perfect. The biggest disadvantage is that if one movie contains multiple mp4 files, it will create a folder for each of them. But if you do a couple of iterations, each time using different extensions in a specific order (start with nfo and other similar extensions, then move on the movie binary extensions, etc) you might be able to do at least most of the work automatically.

@echo off
setlocal

REM store current directory. Using separate variable makes it 
REM easier to change behaviour too.
set dir=%cd%

REM call subroutine for each supported extension.
call :do .info
call :do .mp4
call :do .avi
call :do .mkv

REM Main program done.
echo Press a key to close.
pause
exit /b

:do
set ext=%1
REM loop through all files with the given extension.
for /f "tokens=*" %%f in ('dir /b /on "%dir%\*%ext%"') do (
  REM trim the extension and use the base name as directory name.
  setlocal EnableDelayedExpansion
  set thefile=%%~nf
  echo !thefile!
  md "%dir%\!thefile!"
  REM move all files that start with the same base name.
  move "%dir%\!thefile!*.*" "%dir%\!thefile!\"
)
REM exit subroutine
exit /b
查看更多
Summer. ? 凉城
4楼-- · 2019-01-22 23:08

I think that this will work, but try on a test folder first :

@echo off
for %%a in (*.*) do (
md "%%~na" 2>nul
move "%%a" "%%~na"
)
cd ..
del %%~na
pause

edit: I changed the code, mixed syntax of batch and bash.

查看更多
一纸荒年 Trace。
5楼-- · 2019-01-22 23:09

Just save the below code with .Bat extension in the actual source location and it will do the trick.

@echo off
for %%a in (*.*) do (
md "%%~na" 2>nul
move "%%a" "%%~na"
)
pause

查看更多
登录 后发表回答