How to move files into subdirectories in batch job?
November 7, 2006 10:14 AM   Subscribe

I have a large number of files sitting in a directory. I'd like to automate the following: Take each file, create a subdirectory for it (the name can be anything), and move the file into that subdirectory. Repeat until every file is moved into its own subdirectory. This is in Windows XP (although obviously I could use a .BAT file in MS-DOS). Thanks
posted by mikeand1 to Computers & Internet (24 answers total) 4 users marked this as a favorite
 
If you type this at the command line, it should do what you're asking:

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

This assumes that all the filenames have extensions, and the folder names it creates are the same as the filenames, but without the extensions.

So if you have
test1.txt
test2.txt
test3.txt

They'll end up in
test1\test1.txt
test2\test2.txt
test3\test3.txt
posted by llamateur at 10:25 AM on November 7, 2006


(Now, if you want to put it in a batch file, then you need to double up each of the percent signs, so it would be

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

but then you'll also have the problem of the batch trying move itself, so you'll probably want to put the batch file somewhere else and specify the working directory:

for %%i in (PathToWorkingFolder\*) do mkdir "PathToWorkingFolder\%%~ni" & move "%%i" "PathToWorkingFolder\%%~ni"
posted by llamateur at 10:32 AM on November 7, 2006


Response by poster: ^^ Thanks, that works. But it doesn't work as a .BAT file. Is there any way to do this without having to type it in every time?
posted by mikeand1 at 10:38 AM on November 7, 2006


Response by poster: Whoops, didn't see your second post -- let me try that.

thanks again.
posted by mikeand1 at 10:39 AM on November 7, 2006


Response by poster: Yup, that works great. Thank you for your help.
posted by mikeand1 at 10:53 AM on November 7, 2006


Response by poster: OK, for bonus points: How about a version that will work recursively, processing multiple subdirectories in a directory tree?
posted by mikeand1 at 10:57 AM on November 7, 2006


Or you could save this off as a .vbs, since it's XP:

Dim fso
Dim CurrentFolder
Dim Files
Dim NewFolderName
Dim TruncatedFileName

Set fso = CreateObject("Scripting.FileSystemObject")
Set CurrentFolder = fso.GetFolder(".")
Set Files = CurrentFolder.Files

For Each File in Files
   If UCase(Right(File.Name,3)) <> "VBS" Then
      TruncatedFileName = Left(File.Name, InstrRev(File.Name, ".") - 1)
      NewFolderName = CurrentFolder.Path & "\" & TruncatedFilename
   
      fso.CreateFolder NewFolderName
      File.Move NewFolderName & "\"
   End If
Next
posted by ostranenie at 10:59 AM on November 7, 2006


Best answer: Recursive version:

Dim fso
Dim Folders
Dim CurrentFolder
Dim Files
Dim NewFolderName
Dim TruncatedFileName

Set fso = CreateObject("Scripting.FileSystemObject")
Set MainFolder = fso.GetFolder(".")
ProcessFolder MainFolder

Sub ProcessFolder(CurrentFolder)
   Set Folders = CurrentFolder.SubFolders

   ' Folders first, then files
   For Each Folder in Folders
      ProcessFolder(Folder)
   Next

   Set Files = CurrentFolder.Files
   For Each File in Files
      If UCase(Right(File.Name,3)) <> "VBS" Then
         TruncatedFileName = Left(File.Name, InstrRev(File.Name, ".") - 1)
         NewFolderName = CurrentFolder.Path & "\" & TruncatedFilename
      
       fso.CreateFolder NewFolderName
       File.Move NewFolderName & "\"

      End If
   Next
End Sub
posted by ostranenie at 11:13 AM on November 7, 2006


Response by poster: ^^^ Cool!

So do I have to put a path in there somewhere, or do I just put it in the upper most level of the directory I want to process?

(And I take it I should be careful with it in that case!)
posted by mikeand1 at 11:18 AM on November 7, 2006


(You're probably better off with ostranenie's vbs version, since it's probably a lot safer and less hack-y, but since I bothered to come up with it, here's a batch-based one that works recursively:

for /f "delims=" %%i in ('dir /a-d/s/b') do mkdir "%%~pi\%%~ni" & move "%%i" "%%~pi\%%~ni"

Just run it from the working directory, but again I'd put the batch file somewhere else so it doesn't try to move itself.)
posted by llamateur at 11:30 AM on November 7, 2006


Response by poster: ^^^ Thanks - But it appears ostranenie's version is easier to use, because you don't have to put a path in it. You just put it in the directory you want to process, and click.

But it seems to me one could seriously screw up a computer by putting it somewhere dangerous, so attention must be paid!

In any case, thanks all, this is perfect.
posted by mikeand1 at 11:36 AM on November 7, 2006


Isn't "dot" (.) a substitute for the current directory in DOS/*nix? Or does that not work in batch scripting?

In any event, this is slightly safer (you select the folder with a pop-up dialog before it processes the folder):

Dim fso
Dim CurrentFolder
Dim Files
Dim NewFolderName
Dim TruncatedFileName
Dim MainFolder
Dim sh
Dim wx

Set fso = CreateObject("Scripting.FileSystemObject")
Set sh = CreateObject("Shell.Application")
Set wx = CreateObject("WScript.Shell")

On Error Resume Next
Set MainFolder = sh.BrowseForFolder(0, "Select Folder", 0, 17)
If Err then Err.Clear : WScript.Quit
On Error Goto 0

Set MainFolder = MainFolder.Self
If Not IsObject(MainFolder) Then WScript.Quit
If Not (LCase(Left(Trim(Typename(MainFolder)), 6))="folder") Then WScript.Quit

Result = wx.Popup("Do you want to process " & MainFolder.Path & "???",10, "Process Folder", 36)

If Result = 6 Then
ProcessFolder MainFolder
End If

Sub ProcessFolder(CurrentFolder)
   Set Folders = CurrentFolder.SubFolders

   ' Folders first, then files
   For Each Folder in Folders
ProcessFolder(Folder)
   Next

   Set Files = CurrentFolder.Files
   For Each File in Files
      If UCase(Right(File.Name,3)) <> "VBS" Then
         TruncatedFileName = Left(File.Name, InstrRev(File.Name, ".") - 1)
         NewFolderName = CurrentFolder.Path & "\" & TruncatedFilename
      
       fso.CreateFolder NewFolderName
       File.Move NewFolderName & "\"

      End If
   Next
End Sub
posted by ostranenie at 12:09 PM on November 7, 2006


Can I ask why are you doing this? It seems like putting files in folders named after the files themselves is just going to get you even more disorganized than if they resided in one folder. What practical application does this script have? (Other than serving as a basic reference example to VBScript file operations)
posted by ostranenie at 12:12 PM on November 7, 2006


I asked a question quite similar to this about 8-9 months ago - except that in my case, the subdirectories were already created.
posted by chr1sb0y at 12:19 PM on November 7, 2006


Response by poster: "Can I ask why are you doing this?"

Sure -- We're processing documents, converting them into single-page TIFF images. For example, one document with 1,000 pages will get converted into 1,000 TIFF files. If you process several hundred files of this sort, all in one directory, you end up with a heckuva lot of files in one place.

Thanks again for your help.
posted by mikeand1 at 12:32 PM on November 7, 2006


Response by poster: "I asked a question quite similar to this about 8-9 months ago - except that in my case, the subdirectories were already created."

Right, I actually saw that before I posted my question, but I couldn't figure out how to get it to work the way I wanted it to.
posted by mikeand1 at 12:33 PM on November 7, 2006


I'm with ostranenie, I'm very curious about why you would want to do this. It seems very much like a "X and Y" question.
posted by AmbroseChapel at 12:39 PM on November 7, 2006


That's...kind of understandable, but it seems like the software that converts the 1,000-page documents into TIFFs ought to give you the option to create a subfolder "pages" or "TIFFs" or something, instead of you doing all the work and pre-creating all these folders. You know, since it's sophisticated enough to convert document pages to images, it should do you the favor of making the one measly system call (in this case CreateFolder) and save you the trouble.

I ran into a similar "problem" a few months back when we were using some super-fancy 3D software at work that offered up DOS batch files in lieu of copying large amounts of texture/surface files from one area to another. Why DOS batch files and why not API calls and a nice progress bar? NO idea. And it didn't even execute them for you - you had to manually double-click the newly created .BAT files in the directory they were created in. For the price we paid for the software, that seemed kind of asinine.

But if you (or your company) didn't write the software, then a hacky workaround like mine is better than nothing ;-) I suggest you contact the authors and offer up this suggestion, they might implement it and their users will save future headaches..
posted by ostranenie at 12:59 PM on November 7, 2006


I'm confused too! So now instead of a directory with 1000 tiff files you have 1000 subfolders each with a tiff file instead? Or did I miss something? Sorry for not helping with the question.
posted by Ferrari328 at 1:33 PM on November 7, 2006


Response by poster: "You know, since it's sophisticated enough to convert document pages to images, it should do you the favor of making the one measly system call (in this case CreateFolder) and save you the trouble."

You'd think, but not the case here.
posted by mikeand1 at 2:19 PM on November 7, 2006


Response by poster: "You know, since it's sophisticated enough to convert document pages to images, it should do you the favor of making the one measly system call (in this case CreateFolder) and save you the trouble."

Yes. The other piece of it is that when the documents get loaded into a database, the fact that a group of TIFF images is in a common directory is what tells the database it's all part of one document.
posted by mikeand1 at 2:21 PM on November 7, 2006


Response by poster: "So now instead of a directory with 1000 tiff files you have 1000 subfolders each with a tiff file instead?"

No no. I start with a directory with multiple PDF files, each one of which has multiple pages. I copy each PDF file into a subdirectory, within which one PDF file gets split up into multiple TIFF images. So if I have 100 PDF files at the start, and each one has 1,000 pages, I end up with 100 subdirectories, each one of which has 1,000 TIFF images.

The other piece of it is that when the documents get loaded into a database, the fact that a group of TIFF images is in a common directory is what tells the database it's all part of one document.
posted by mikeand1 at 2:24 PM on November 7, 2006


Again with the puzzlement, and as with Ferrari, I apologise for not helping, but what is better about having 1,000 dirs (and 2,000 files in all) instead of 1,000 TIFs?
posted by AmbroseChapel at 2:29 PM on November 7, 2006


Response by poster: Suppose I have 100 PDF files, and each one has 1,000 pages.

If I don't farm them out into subdirectories, but merely convert the PDF files to single-page TIFF images, I end up with 100,000 files in one directory.

Have you ever tried that in Windows? It's a big problem.

Also, the program that loads the images into a database thinks that all the images in a subdirectory belong to one document. So if I don't put them into subdirectories, the database will think I have a single document with 100,000 pages, as opposed to 100 documents with 1,000 pages each.
posted by mikeand1 at 2:39 PM on November 7, 2006


« Older Why does dark chocolate make me sneeze?   |   I actually said, "honey, will you just hug me for... Newer »
This thread is closed to new comments.