Friday, May 08, 2009

Some Handy BATCH and VB Scripts for Organizing Files

Here are four scripts and batch files that come in handy sometimes when you organize or clean-up files and folders on your hard disk. You can use the provided scripts as you see fit. They are provided “as is” and are not supported. Also be aware that I will not take any responsibility for any damage or harm that the scripts might cause. You use them at your own risk. You are free to use, copy, modify and delete them (Freeware).

Move Files to Sub Folders Alphabetically

The simple batch script creates the sub folders A, B, C, D … Z and 0-9 in the current directory where the batch is executed and moves all files in that same directory to the corresponding sub folder.

For example, all files starting with “a” or “A”, like “Anna.zip” or “achim.gif”, will be moved to the sub folder “A”. All files that do not start with a letter from the English alphabet, such as numbers (“0", “1” … “9”), special characters like “!”, “_”, “$” etc. and foreign characters like “ä” or “é” are moved to the sub folder “0-9

I wrote in march a post about organizing file collections on your computer and provided also some scripts to help you sort and catalog files. I found a much simpler way of doing the same stuff as the batch script “!organize.bat” and the VBScript script !folders.vbs”. It does not replace the script “!dirlist.vbs”, which creates the file index. If you want to use “!dirlist.vbs” with this new and shorter script to move files into sub folders by alphabet, simply add the following line of code after line 7 (after “Move * 0-9” and before “goto :EOF”):

wscript !dirlist.vbs

This batch also does one thing slightly different. It moves to the sub folder “0-9” not just files that start with a number, but also all other files that do not start with a letter from the English alphabet.

MoveToAlphabetSubFolders.bat

   1: @echo off
   2:  
   3: for %%f in (a b c d e f g h i j k l m n o p q r s t u v w x y z 0-9) do Call :MoveFiles "%%f"
   4: goto :EOF
   5:  
   6: :MoveRest
   7: Move * 0-9
   8: goto :EOF
   9:  
  10: :MoveFiles
  11: if NOT EXIST %1 MD %1
  12: if %1==0-9 Goto :MoveRest
  13: for %%f in (%1*) do move "%%f" %1

Remove Empty Folders and Sub Folders

This little batch file scans the directory that was provided as a parameter and all its sub-directories for empty folders and deletes them, including the provided folder itself, if it is empty as well (or became empty after all empty sub-folders were removed).

RemoveEmptySubFolders.bat


   1: @echo off
   2: set Folder="%~1"
   3: if %Folder%=="" @echo Syntax RemoveEmptySubFolders Folder&goto :EOF
   4: if not exist %Folder% @echo Syntax RemoveEmptySubFolders Folder - %Folder% not found.&goto :EOF
   5: setlocal
   6: :: REMOVE EMPTY SUBFOLDERS
   7: for /f "tokens=*" %%A in ('dir /ad /s /b %Folder% ^|Sort /Reverse') do (
   8:  RmDir "%%A" 2>NUL
   9: )
  10: :: REMOVE FOLDER, IF EMPTY
  11: RmDir %Folder% 2>NUL
  12: endlocal

Move Files to Folder and Auto Rename Duplicates

This tool requires Windows Script.

This little VBScript moves all files from the source folder, including all files from it’s sub folders to the specified target folder and renames files, if a file with the same name already exists at the destination directory. The rename also works, if you have several files with the same name (such as a file with the same name in several sub directories of the source folder). The renamed file is named FILENAME[X}.EXT, where X starts with 1 and increments by 1 if already another file with the same name exists. For example

1. Source Dir\file.zip
2. Source Dir\Sub Folder1\file.zip
3. Source Dir\Sub Folder2\file.zip

would be moved and renamed to “Target Dir” like this

1. Target Dir\file.zip
2. Target Dir\file[1].zip
3. Target Dir\file[2]/zip

If you specify the target directory to be the same as the source directory, the script will automatically ignore the files in the source directory root and only process the files in the source directories sub folders. This feature is quite nice, if you want to consolidate all files in a directory tree in the root directory of the tree itself.

If you run the script without any parameters, you will be asked to first specify the location of the source directory (it will show as default value the path to the current directory where the script was executed) and then the target directory (it will show as default value to parent directory of the entered source directory).

Execution of the script without any parameters:

Wscript.exe MoveFilesAutoRenDup.vbs

You can also provide the source and also the destination directories as parameters to the script and you won’t be prompted to enter one anymore.

Execution of the Script with source and destination directory provided as command line parameters:

Wscript.exe MoveFilesAutoRenDup.vbs X:\SOURCEFOLDER X:\DESTINATIONFOLDER

MoveFilesAutoRenDup.vbs


   1: Dim FSO: Set FSO = CreateObject("Scripting.FileSystemObject")
   2: Dim arguments: Set arguments = Wscript.arguments
   3: Const ForAppending = 8, ForReading = 1, ForWriting = 2
   4: Dim iFilesCount: iFilesCount  = 0
   5: Dim  sSrc, sDest, DC, sExt, sBase, oFOld
   6: Dim sTo, sFrom
   7:  
   8: if arguments.unnamed.count = 0 then
   9:   sFrom = "N*A"
  10:   Do While sFrom <> "" and FSO.FolderExists(sFrom) = false
  11:   sFrom = InputBox("Move All Files and Auto Rename " & _ 
  12:           Dupes","Enter Source Directory" & _
  13:           ": ", fso.GetAbsolutePathName("."))
  14:   Loop
  15:   if sFrom = "" then
  16:      WScript.Quit(1)
  17:   End if
  18: else
  19:   sFrom = arguments.unnamed.Item(0)
  20: end if
  21: if not FSO.FolderExists(sFROM) then
  22:    WScript.Quit(2)
  23: end if
  24:  
  25: if arguments.unnamed.count = 1 then
  26:   sTo="N*A" 
  27:   Do While sTo <> "" and FSO.FolderExists(sTo) = false
  28:   sTo = InputBox("Move All Files and Auto Rename Dupes","Source Directory: " & _ 
  29:         vbcrlf & sFrom & vbcrlf & "Enter Destination Directory" & _
  30:         ": ", FSO.GetParentFolderName(sFrom))
  31:   Loop
  32:   if sTo = "" then
  33:      WScript.Quit(1)
  34:   end if
  35: else
  36:   sTo = arguments.unnamed.Item(1)
  37: end if
  38: if not FSO.FolderExists(sTo) then
  39:    WScript.Quit(2)
  40: end if
  41:  
  42: Set oFold = FSO.GetFolder(sTo)
  43: if lcase(sTo) <> lcase(sFrom) then
  44:   ShowFiles oFold.Path
  45: end if
  46: ShowSubFolders oFold
  47:  
  48: Wscript.echo iFilesCount  & " files moved"
  49: '========================================
  50: Sub ShowSubFolders(Folder)
  51:   Dim SubFolder
  52:   For Each Subfolder in Folder.SubFolders
  53:     ShowFiles Subfolder.Path
  54:     ShowSubFolders Subfolder
  55:   Next
  56: End Sub
  57: '----------------------------------------
  58: Sub ShowFiles(sPath)
  59:   Dim oFile, oFolder
  60:   iFolderCount = iFolderCount + 1
  61:   Set oFolder = FSO.GetFolder(sPath)
  62:   iFilesCount = iFilesCount + oFolder.Files.count
  63:   For each oFile in oFolder.Files
  64:     sDest = FSO.BuildPath(sTo, oFile.Name)
  65:     sExt = FSO.GetExtensionName(sDest)
  66:     sBase = left(oFile.Name,len(oFile.name)-len(sExt)-1)
  67:     DC = 1
  68:     Do While FSO.FileExists(sDest) = true
  69:       DC = DC + 1
  70:       sDest = FSO.BuildPath(sTo, sBase & "[" & DC & "]." &  sExt)
  71:     Loop
  72:     sSrc = FSO.GetAbsolutePathName(FSO.BuildPath(sPath,oFile.Name))
  73:     FSO.MoveFile sSrc, sDest
  74:   Next
  75: End Sub
  76:  
  77:  

Determine the Short Path (8.3 DOS Name) of the Current Directory


This tool requires Windows Script.

If you still use some old 16bit or DOS applications that do not support the long file names of FAT32 and NTFS, then you know that in order for those tools to work, the short 8.3 DOS Name of directories and files must be used with the application. The dos command “DIR /X” provides that information, but only for the current directory. If you need to know the short name of the entire path to a sub directory a couple levels down from the drive root, this approach becomes pretty cumbersome.

Here is a little script that helps with that. You can execute it from the command prompt at the directory where you want to know the short name by typing:

wscript.exe c:\tools\shortpath.vbs

I assume that the script was saved in the directory c:\tools, if you saved it somewhere else, change the command accordingly. 

You can also add it to Windows Explorer as a shell extension like in this example below. How to install the script as a shell extension in Windows XP is explained in the last paragraph of this post.

ContextMenu1

Example for the Long Path in Windows 32 bit:

C:\Documents and Settings\Administrator\Local Settings\Application Data\Microsoft

Short 8.3 DOS Path Equivalent (on my computer, might differs from yours)

C:\DOCUME~1\ADMINI~1\LOCALS~1\APPLIC~1\MICROS~1

The script returns the short path in an input box that you can easily copy and paste it from there into your application or document.

Ashortpath

Here is the source code of the script.

shortpath.vbs


   1: Dim oFso: Set ofso = CreateObject("Scripting.FileSystemObject")
   2: Dim arguments: Set arguments = Wscript.arguments
   3:  
   4: if arguments.unnamed.count = 0 then
   5:   Path = ofso.GetAbsolutePathName(".")
   6: else
   7:   Path = arguments.unnamed.Item(0)
   8: end if
   9:  
  10: Set tmpf = ofso.GetFolder(Path)
  11: PathShort = tmpf.ShortPath
  12: Set tmpf = Nothing
  13:  
  14: a = InputBox("8 Character DOS Short Path","Path:", PathShort)
  15: Set oFso = Nothing

Using the Tools from the Command Prompt


You can run all of the provided scripts and batch files from the DOS command prompt. To open a command prompt on your computer, click on “Start” and then on “Run”. Type “cmd” and then press “Enter”. If you copied the batch files to a location that is included in the Windows %Path% environment variable, such as the Windows system directory (usually c:\Windows) or the System32 directory (usually c:\Windows\System32) then you do not have to provide the path to the BATCH files in order to be able to execute them. You can simply type the name of batch file and Windows will find it automatically and execute it.

Make sure that you are in the right directory when you call the batch script. If you open a command prompt the way I described it above, you are usually located at your users home directory (usually c:\documents and settings\USERNAME, where USERNAME is the name of the current Windows user). You would have to navigate to the right directory using the “CD” command (type “help cd” and then press “enter” to open the help documentation for the “CD” command)

commandprompt1

To execute a VBScript script from the command prompt, you have enter first “wscript.exe”, followed by the path and the file name of the script, even if the .VBS file is located in a directory that is included in the %Path% environment on your computer. “wscript.exe” is a tool, which is located in the Windows System32 directory (usually c:\Windows\System32) and processes the VBScript code. Unlike with .BAT files, Windows is not capable of executing VBScript code directly. If you get an error that “wscript.exe” was not found, then you have not Windows Script installed on your system (it is usually installed by default). You can download and re-install the Windows Script components from the Microsoft web site here.


commandprompt2

To open quickly a command prompt in the folder that you selected in Windows Explorer, add a the “Command Prompt Here” Explorer Extension to your System Registry. If you do not know how to do it manually with the Regedit.exe tool from Windows, copy the code below and save it to a file with the name “CmdHere.reg”.

CmdHere.reg


   1: Windows Registry Editor Version 5.00
   2:  
   3: [HKEY_CLASSES_ROOT\Directory\shell\Command &Promt Here]
   4:  
   5: [HKEY_CLASSES_ROOT\Directory\shell\Command &Promt Here\command]
   6: @="cmd.exe /k cd \"%1\""

Double-click on the file and Windows should ask you if are sure that you want to import the contents of the file CmdHere.reg into the system registry. Acknowledge with “OK” and the extension will be installed and ready to use.

areyousure

Add Tools to Windows Explorer Context Menu for Folders


The Paragraph before already showed you how to create a Windows Explorer shell extension for the Folders context menu, but let me show you some specific examples for the tools that I provided in the first segment of this blog post.


I assume that you copied all the scripts and batch files to a folder called c:\tools. If you want to use a different folder or file name for the scripts, simply adjust the .REG file samples below. Notice the two back slashes (“\”) instead of one? The second one is necessary to escape the “\” of the path name, that the script will not interpret it, but take it as a literal string value. If you forget to change a single back-slash to a double-back-slash, an error will occur if you try to execute/import it. You do not have to specify the path to the batch script at all, if you copied it to a  directory that is included in the %PATH% environment of Windows, such as the Windows directory and the System32 directory of the system.

You can also create one .REG file to install all the scripts and batch files to the Explorer context menu. Make sure that the line “Windows Registry Editor Version 5.00” only appears once in the file at the very top and not multiple times, because that would cause errors, if you try to import it to your registry database.

Here is an example for the registration of the MoveToAlphabetSubFolders.bat


The “Move to A-Z” that you see in the code below is the Label for the context menu. If you want it to say something different, replace the two instances in the code with your label text.

The other script “RemoveEmptySubFolders.bat” requires as parameter the folder name and location to process.
To execute the batch script for the current folder selected in the context menu, add the parameter "%1” to the command. Line 6 of the .REG file below would look like this. Notice the “\” before the (“), like for the “\” of the path is it necessary to “unescape” the double-quotes character to prevent interpretation of the character.

@="C:\\tools\\RemoveEmptySubFolders.bat \"%1\""

MoveToAlphabetSubFoldersInst.reg



   1: Windows Registry Editor Version 5.00
   2:  
   3: [HKEY_CLASSES_ROOT\Directory\shell\Move to A-Z]
   4:  
   5: [HKEY_CLASSES_ROOT\Directory\shell\Move to A-Z\command]
   6: @="c:\\tools\\MoveToAlphabetSubFolders.bat"

Here is the example for one of the VBScript tools. Notice that the command starts with wscript.exe followed by the location and name of the script. This is necessary, because Windows does not execute VBS scripts automatically like it does with BAT (Batch) scripts.

ShortPathInst.reg


   1: Windows Registry Editor Version 5.00
   2:  
   3: [HKEY_CLASSES_ROOT\Directory\shell\Short Path]
   4:  
   5: [HKEY_CLASSES_ROOT\Directory\shell\Short Path\command]
   6: @="wscript.exe c:\\tools\\shortpath.vbs"

You can download all BATCH files, VBScript files and REG files from this post as one ZIP compressed archive:

Download FileToolsCodeAndRegFiles.zip

Also included in the archive are the .REG files: MoveFilesAutoRenDupInst.reg and RemoveEmptySubFoldersInst.reg to install the other two scripts to the Windows Explorer context menu; the .REG file InstallAll.reg to register all 4 scripts and the “Command Prompt Here” extension to Windows Explorer and UnInstallAll.reg to remove all 5 extension from Windows Explorer.

Cheers!

Carsten aka Roy/SAC

No comments:

Post a Comment

Hi, thanks for taking the time to comment at my blog.

Due to spam issues comments are not immediately posted on the site and require my manual approval first, before they become visible.

I try to approve comments as quickly as possible and usually within 24 hours.

To be notified about follow up comments that are made after yours, use the subscribe option with your email address and you will receive an email alert, if somebody else comments at this post in the future.

Also check out the rest of the website beyond this blog, visit RoySAC.com. Also see my YouTube channels, SACReleases for intros and demos.

Cheers!
Carsten aka Roy/SAC

Note: Only a member of this blog may post a comment.