Will a .BAT file move these files for me?
February 6, 2006 10:18 AM   Subscribe

I need to move thousands of files (01_preview.jpg, 02_preview.jpg, 03_preview.jpg, etc.) into matching (pre-existing) folders whose names are basically the same as the filenames (folder names are 01, 02, 03, etc.) I'm on a Windows box. Is this a good job for a .BAT file? Can you help me write such a .BAT file? (Online tutorials for batch files have not helped me so far.)

So 01_preview.jpg goes into the folder named 01, 02_preview.jpg goes into the folder named 02, etc... Thanks for any pointers or outright cheating help.
posted by chr1sb0y to Computers & Internet (15 answers total)
 
If I had time, I'd write it for you, but I need to get to work soon. :)

Anyway, check out looping in batch files. You'll want to use a counter variable to determine where you'll put each file in each iteration. I think you can accomplish this using the 'goto' call, but I haven't used batch files in a long time. It's times like these you really appreciate perl.
posted by blueplasticfish at 10:34 AM on February 6, 2006


If you are willing to install Cygwin on your box, you can use this at the bash prompt:

for source in $(ls *.jpg); do target=`echo $source | awk -F'_' '{print $1}'`; mv $source $target/$source; done

That whole thing goes on one line, by the way.
posted by Cironian at 10:39 AM on February 6, 2006


I use Flexible Renamer for this and similar problems. Take care to download the English version rather than the German one.
posted by smackfu at 10:41 AM on February 6, 2006


Bat file won't do it. This script should do it for you - just moves each jpg file into a folder that has the name of the first two characters of the filename. Will need some editing if you get to three digits, but gives the idea. Save the following script as a .vbs file. using notepad, edit the srcpath to be the one you want to do the sorting in, then run it by double clicking. Should work for you, but I would try on a copied sample in a safe directory, since there's no undo.

-gage


Dim fso
Dim folder
Dim srcFolder
Dim dstFolder

srcFolder = "C:\temp\jpgtest\"


Set fso = CreateObject("Scripting.FileSystemObject")
Set folder = fso.GetFolder(srcFolder)
For Each File In folder.Files
Set fs = fso.GetFile(File.Name)
If fso.GetExtensionName(fs) = "jpg" Then
dstFolder = srcFolder & Left(File.Name, 2)
If Not fso.FolderExists(dstFolder) Then
fso.CreateFolder dstFolder
End If
fso.MoveFile File.Path, dstFolder & "\" & File.Name
End If
Set fs = Nothing
Next
posted by gage at 10:49 AM on February 6, 2006


assuming the folders already exist, and are subdirectories of whereever your images are stored. If they're not you'll have to adjust the .\01 bits :

---- snip ----
move 01*.jpg .\01
move 02*.jpg .\02
move 03*.jpg .\03
move 04*.jpg .\04
...
move 09*.jpg .\09
---- snip ----
It's stone simple, but why make things harder than they need to be? Although if you're compelled to fancy things up, I'd suggest creating a Windows Script Host script rather than downloading cygwin just for the purpose of humping things through awk.
posted by boo_radley at 10:58 AM on February 6, 2006


crap, beaten.
posted by boo_radley at 11:01 AM on February 6, 2006


http://www.1-4a.com/
posted by Izzmeister at 11:10 AM on February 6, 2006


set counter=0

:loop
set /a counter=%counter%+1
move %counter%*.jpg C:\somefolder\%counter%\
goto loop


doesn't have any error handling, and will loop forever (maybe dying hard when there are no files left), but it should do the job, or at least get you started.

I find it interesting that so many people feel compelled to tell you ways to solve the problem that involve installing tools. I guess when when you've got a trick hammer, you figure out how to make every problem a nail.
posted by Four Flavors at 11:13 AM on February 6, 2006


You don't say which version of windows - it makes a difference.

If we assume XP then try this

@echo off
for %%G in (*.jpg) do call :move_sub %%G
goto :eof

:move_sub
set _file=%1
set _folder=c:\newplace\%_file:~0,2%

move %_file% %_folder%
posted by Lanark at 11:14 AM on February 6, 2006


Best answer: Save the following with a .wsf extension. It will ask you for a source and destination directory, the file extension to look for and copy, and it will log all errors and give you a final tally on the files that were successfully copied over.

I really wish I could tabulate it better. If you decide to try it out and have any issues, just email me. Email is in the profile.

-- COPY EVERYTHING BELOW THIS LINE --
' The following script will move files from one folder over to
' folders named exactly the same as the files minus their extension.
'
' You must specify the folder location of the files, the base folder
' that contains all the destination folders and the file extension.
' The script will avoid all files without the same extension, and
' if the child destination folder does not exist, the file will not
' be copied over.
'
' Usage: wscript move_files.wsf
<package>
<job id="move_files">
<script language="vbscript">
Option Explicit
On Error Resume Next

Dim strSourceFolder, strDestinationFolder, strFileExtension, strLogFile
strSourceFolder = InputBox("Base Folder:" & vbCRLF & "Enter the fully qualified path for the base folder that contains the files that are to be moved. TRAILING SLASH IS NECESSARY!", "Move files - Step 1")
strDestinationFolder = InputBox("Destination Folder:" & vbCRLF & "Enter the fully qualified path for the destination folder that contains the directories that correspond with the filenames (without extensions). TRAILING SLASH IS NECESSARY!", "Move files - Step 2")
strFileExtension = InputBox("File extension:" & vbCRLF & "Enter the file extension of the files you want to move. This script will avoid all files that do not match this extension.", "Move files - Step 3")
strLogFile = "move_files.log"

' Declare objects.
Dim FSO: Set FSO = CreateObject("Scripting.FileSystemObject")

Const ForReading = 1, ForWriting = 2, ForAppending = 8

' Setup the logging feature.
Dim objLogFile : Set objLogFile = FSO.OpenTextFile(strLogFile, ForWriting, True)

objLogFile.WriteLine "Generated on: " & Date
objLogFile.WriteLine ""

' Check to ensure that the values entered are accurate.
If FSO.FolderExists(strSourceFolder) And FSO.FolderExists(strDestinationFolder) Then
' The folders exist, proceed with copying the files.
Dim objSourceFolder, colFiles, objFile, strChildFolderName, intCounter

Set objSourceFolder = FSO.GetFolder(strSourceFolder)
Set colFiles = objSourceFolder.Files
intCounter = 0

' Run through the files in the source folder.
For Each objFile In colFiles
If Right(objFile.Name, 4) = strFileExtension Then
strChildFolderName = Left(objFile.Name, Len(objFile.Name) - 4)
If FSO.FolderExists(strDestinationFolder & strChildFolderName) Then
objFile.Copy strDestinationFolder & strChildFolderName & "\", True
If Err Then
objLogFile.WriteLine "File NOT copied (" & Err.Number & ": " & Err.Description & "): " & objFile.Name & " to " & strDestinationFolder & strChildFolderName
Else
intCounter = intCounter + 1
End If
Else
objLogFile.WriteLine "File NOT copied (destination folder does not exist): " & objFile.Name & " to " & strDestinationFolder & strChildFolderName
End If
Else
objLogFile.WriteLine "File IGNORED (incorrect file extension): " & objFile.Name
End If
Next

Set objSourceFolder = Nothing
Set colFiles = Nothing
Else
' Either the source or destination folder does not exist.
Msgbox "Either the source or destination folder does not exist. Please enter valid pathnames."
End If

objLogFile.WriteLine "Files copied: " & intCounter
objLogFile.Close
Set objLogFile = Nothing
Set FSO = Nothing
WScript.Quit
</script>
</job>
</package>
-- COPY EVERYTHING ABOVE THIS LINE --
posted by purephase at 11:17 AM on February 6, 2006


Response by poster: MORE INFO: I oversimplified when I gave the example of 01_prev.jpg, 02_prev.jpg, etc. My images are actually named various things (server_room_prev.jpg, man_on_phone_prev.jpg, meeting_34_prev.jpg, etc.) They all end in "_prev.jpg", and the folder names match the image names (except for the "_prev.jpg" part). Thanks much for all suggestions so far - I am trying out a couple. Unfortunately, so far, I cannot see how 1-4a Renamer or Flexible Renamer can help me out.
posted by chr1sb0y at 11:38 AM on February 6, 2006


OK in that case try:

@echo off
for %%G in (*.jpg) do call :move_sub %%G
goto :eof

:move_sub
set _file=%1
set _folder=c:\newplace\%_file:~0,-9%

move %_file% %_folder%
posted by Lanark at 11:49 AM on February 6, 2006


Best answer: Well, Flexible Renamer is good if you know regexps. You would set it to Advanced Rename, Regexp mode, and then set the Search for to:

(.*)_prev.jpg

And the Replace with to:

\1/\0
posted by smackfu at 12:23 PM on February 6, 2006


Best answer: From my example above:
If Right(objFile.Name, 4) = strFileExtension Then
strChildFolderName = Left(objFile.Name, Len(objFile.Name) - 4)

Change it to:
If Right(objFile.Name, Len(strFileExtension) Then
strChildFolderName = Left(objFile.Name, Len(objFile.Name) - Len(strFileExtension)

This will allow the entered file extension to be anything you like. So, instead of just entering ".jpg", you could enter "_prev.jpg" and it would just as well.
posted by purephase at 12:33 PM on February 6, 2006


Just realized the folly of my ways (and thanks to chr1sb0y for pointing it out to me in an email) I'm missing some parentheses in the re-worked code above. Here's the right code:

If Right(objFile.Name, Len(strFileExtension)) Then
strChildFolderName = Left(objFile.Name, Len(objFile.Name) - Len(strFileExtension))
posted by purephase at 7:55 PM on February 6, 2006


« Older working abroad as a doctor   |   Alternatives for documenting a SDLC? Newer »
This thread is closed to new comments.