Windows Batch to rename <int>_body.html to <int>.html - batch-file

Can't seem to nail this one down... Is there a programmatic/batchish way to rename a set of files in the same directory from 1_body.html, 2_body.html, etc to 1.html, 2.html?
I'm just a regular user, so I wont have permissions to do anything too fancy :).

As it always seems to go, after hours of digging I found the answer right after posting this...
rename ?_body.html ?.html
rename ??_body.html ??.html
rename ???_body.html ???.html
Took care of it.

You could also do it using VBScript. Here's an example (based on this script):
Set objFSO = CreateObject("Scripting.FileSystemObject")
strFolder = CreateObject("Scripting.FileSystemObject").GetAbsolutePathName(".") ''# Current directory
Set objFolder = objFSO.GetFolder(strFolder)
For Each strFiles In objFolder.Files
If objFSO.GetExtensionName(strFiles) = "html" Then
strComponents = Split(strFiles.Name, "_")
strFiles.Name = strComponents(0) + ".html"
End If
Next
Save the above as something.vbs in the directory it is to run and double click to run it.

Related

VBScript (.vbs) Produces Errors When Executed From A 2nd .vbs

We have a vendor who sends us CSV index files to be used with our OnBase document import software. If the CSV file was generated using one of our institutional forms, OnBase ingests them w/o error as we have set up corresponding Document Types that match the 1st delimited value in the CSV file. However, if the CSV file was generated using a vendor form, the 1st delimited value is slightly different and creates OnBase indexing errors. Our vendor uses this CSV format for many of their clients and have indicated it cannot be customized to match our current OnBase Document Types (w/o $$$).
I was tasked with identifying a workaround and found another institution using VBScript to create CSV index files before OnBase processing. After some collaboration, I was able to code a similar approach using VBScript. However, since we already receive index files, our approach identifies how many CSV files are in a target folder, via a loop opens each one, identifies the 1st delimited value within the CSV file, compares that value via a switch case method, updates the 1st delimited CSV value based on the switch case method, then saves the file, until the loop ends (loop value = # of files in target folder - 1...to account for the vbs file). When I click on the vbs file, it works like a charm!
Here is where the trouble begins. If I try and run the vbs file from another vbs file, the script produces errors: File not found. I included some debugging code, and I can see it correctly counts the number of files in the target folder, etc. When I thought it wasn't finding the target folder, I accounted for that by harcoding the path during testing. Even when I am sure it is finding the correct target folder, I'm receiving the same File Not Found error. If I double-click the exact same vbs file, it runs without error and all CSV files are correctly updated.
Update #Ansgar Wiechers resolved the issue of finding and keeping the correct file path value. But, I'm still receiving a File Not Found error at line 163.
Line 163
Char 1
Error: File Not Found
Code: 800A0035
Source: Microsoft VBScript runtime error
On a side note, I've also noticed that my vbs script will only run one time before you have to copy/paste a new instance in the target folder before running it again. Which leads me to think my loop never ended, so I included a debugging MsgBox that displays after the loop has ended (or think it has ended) and right before the WScript.Quit command. These are the last two lines in the script and the message box successfully displays. I'll include code below from both my vbs files.
VBScript file #1 (asterisks masking personal info):
Dim CurrentDirectory
Set FSO = CreateObject("Scripting.FileSystemObject")
CurrentDirectory = "C:\Users\*******\Desktop\ProVerify\Testing\ERROR_FILES\"
FSO.CopyFile "C:\Users\*******\Desktop\ProVerify\Testing\Old Source Files\VBScript_PV_Form_conversion.vbs", CurrentDirectory
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run "C:\Users\*******\Desktop\ProVerify\Testing\ERROR_FILES\VBScript_PV_Form_conversion.vbs"
WshShell.Popup "VBS file will be deleted in 10 seconds...", 10
FSO.DeleteFile "C:\Users\*******\Desktop\ProVerify\Testing\ERROR_FILES\VBScript_PV_Form_conversion.vbs"
WScript.Quit
VBScript file #2 (in target folder with CSV files; removed switch case code for this post to save space):
' Declare vars
Dim intDebug, sFile, strDirectory, numFiles, sLine, aLine
intDebug = 1
' Find path of folder where script file resides & Set Object vars
Set objFSO = CreateObject("Scripting.FileSystemObject")
strDirectory = objFSO.GetParentFolderName(WScript.ScriptFullName)
Set objFolder = objFSO.GetFolder(strDirectory)
' Count number of files in folder
numFiles = objFolder.Files.Count - 1
If intDebug = 1 Then
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Popup "File Count: " & numFiles, 2
WshShell.Popup "File Path: " & strDirectory, 2
Else
End If
If numFiles <= 1 Then
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Popup "No Files to Process", 2
WScript.Quit
Else
End If
'Loop through each file in folder
For Each folderIdx In objFolder.Files
Set oStream = folderIdx.OpenAsTextStream
'Read file and capture first delimeted value
sLine = oStream.ReadLine
oStream.Close
aLine = Split(sLine, ",")
' Compare delimeted value & update to OnBase DocType naming convention
Select Case aLine(0)
[*****case method here*****]
End Select
' Create replacement delimited value
sLine = ""
For i = LBound(aLine) To UBound(aLine)
sLine = sLine + aLine(i) + ","
Next
'Open file and replace updated delimeted value
Set oStream = objFSO.OpenTextFile(folderIdx.Name, 2)
oStream.WriteLine Left(sLine, Len(sLine)-1) ' Remove comma from updated delimeted value
oStream.Close
Next
'Reset Object vars
Set oStream = Nothing
Set objFSO = Nothing
Set objFolder = Nothing
If intDebug = 1 Then
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Popup "Conversion Complete", 2
Else
End If
WScript.Quit
In summary:
This code works fine (once) when I double-click; then a new instance needs to be copied/pasted into target folder before double-clicking will run the file again.
Code produces error when run via another vbs file, line 163, File Not Found.
I'm pretty sure this could be accomplished within OnBase, but our OnBase Sys Admin insists I am incorrect. The 51 OnBase User Guides referring to VBScipting over 1,500 times, tells me otherwise. That said, for now I've tasked with finding a solution outside of OnBase. Feel free to comment on this topic, too.
Errors like the one you describe are usually caused by incorrect assumptions about the working directory of a script.
Your folder structure apparently looks somewhat like this (names shortended for brevity):
C:\base\folder
├── ERROR_FILES
│   ├── a.csv
│   ├── b.csv
: :
│   └── second.vbs
└── first.vbs
When you double-click the script second.vbs the working directory is C:\base\folder\ERROR_FILES. However, when you double-click first.vbs the working directory is C:\base\folder. Invoking C:\base\folder\ERROR_FILES\second.vbs from there DOES NOT change the working directory for second.vbs.
Now let's take a look at the code in your second script:
strDirectory = objFSO.GetAbsolutePathName(".")
'***********FOR TESTING ONLY**********************
If strDirectory = "C:\Users\*******\Desktop\ProVerify\Testing" Then
strDirectory = objFSO.GetAbsolutePathName(".") & "\ERROR_FILES"
Else
End If
'***********FOR TESTING ONLY**********************
Set objFolder = objFSO.GetFolder(strDirectory)
...
For Each folderIdx In objFolder.Files
Set oStream = objFSO.OpenTextFile(folderIdx.Name, 1)
...
Next
The "FOR TESTING ONLY" section kind of tries to account for the working directory difference by appending "\ERROR_FILES" to strDirectory, which allows you to enumerate the content of that folder. However, running objFSO.OpenTextFile(folderIdx.Name, 1) still attempts to open each file from the current working directory, which is still C:\base\folder.
To avoid this issue run objFSO.OpenTextFile(folderIdx.Path) or, better yet, use the object's OpenAsTextStream method. Also, when your script is residing in the same folder as your data files it's better to get the directory from the script path rather than appending a particular subfolder to the working directory (which may not be what you think it is).
Change the above code fragment to something like this, and it will do what you want:
strDirectory = objFSO.GetParentFolderName(WScript.ScriptFullName)
Set objFolder = objFSO.GetFolder(strDirectory)
...
For Each folderIdx In objFolder.Files
Set oStream = folderIdx.OpenAsTextStream
...
Next
Use the same approach when you open the file for writing:
Set oStream = folderIdx.OpenAsTextStream(2)

Print multiple copies of pdf from script file

I would like to silent print a PDF file multiple times. I don't really mind what implementation is used, but due to being in a corporate environment I cannot easily install unsupported software :(.
I am currently using the following VBscript but could switch to any other implementation:
TargetFolder = "<path to folder>"
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.Namespace(TargetFolder)
Set colItems = objFolder.Items
For Each objItem In colItems
For i = 1 To 13
objItem.InvokeVerbEx ("Print")
Next
Next
This spools the job 13 times though. Is there a way to do this as a single job?
I also saw a suggestion for printing using adobe reader that looked like this:
AcroRd32.exe /t <file.pdf> <printer_name> <printer_driver> <printer_port>
But I couldn't find any reference material for passing the number of copies as a parameter.
I just found this questions which is essentially the same:
Programatically print multiple copies from command line
It appears that looping through and sending the file multiple times is the only solution without additional software.

Launch two Explorer windows side-by-side

Is there a way to launch two Explorer windows side-by-side (vertically tiled) with a Batch script?
If not, how might I do this with VBS?
I have modified the VBS script above by Hackoo to do exactly what the OP wants...
The comments in the script explain exactly what it will do.
If the two windows don't set into correct position, increase the 'Sleep' time and try again.
If you want a horizontal split, use 'objShell.TileHorizontally'.
Option Explicit
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''' Launches two Explorer windows side-by-side filling the screen dimensions.
''' Minimizes all current open windows before launch; if this is not done,
''' the current open windows will also be resized along with our two windows.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Dim Calc,AppData,objShell
Calc = "%windir%\system32\calc.exe"
AppData = "%AppData%"
Set objShell = CreateObject("shell.application")
objShell.MinimizeAll
Call Explore(Calc)
WScript.Sleep 800
Call Explore(AppData)
WScript.Sleep 800
objShell.TileVertically
Set objShell = nothing
'*****************************************************
Function Explore(Path)
Dim ws
set ws = CreateObject("wscript.shell")
Explore = ws.run("Explorer /n,/select,"& Path &"")
End Function
'*****************************************************
This might be in the same category as your question. :)
How can a batch file run a program and set the position and size of the window?
Unfortunately it seems that its not possible without any external third part software in batch. Probably easier in VBS - if so the answer should be in the link.
Try this code :
Option Explicit
Dim Calc,AppData
Calc = "%windir%\system32\calc.exe"
AppData = "%AppData%"
Call Explore(Calc)
Call Explore(AppData)
'*****************************************************
Function Explore(Path)
Dim ws
set ws = CreateObject("wscript.shell")
Explore = ws.run("Explorer /n,/select,"& Path &"")
End Function
'*****************************************************

Recursively search sub-folders and delete all files in sub-folders older than 6-months

We have a directory structure like this
..\Document Name_archive\YYYY\MonthName
so for example we have many sub-folders (within different document name folders) called \2014\January ... etc
We'd like to remove all the folders and their contents that have a created date older than 180 days.
We'd prefer to just use a batch file script, but perhaps a VBScript is better if we need to recursively search.
What's the best way please?
Here's a VBScript solution that uses a recursive function.
' Global FileSystemObject
Set objFSO = CreateObject("Scripting.FileSystemObject")
' Start at the root
DoFolder "c:\document_root\"
' Recursive function
Sub DoFolder(strFolder)
With objFSO.GetFolder(strFolder)
For Each objFile In .Files
If objFile.DateCreated < Date - 180 Then objFile.Delete
Next
For Each objFolder In .SubFolders
DoFolder objFolder.Path
Next
' Checked every file and subfolder. If this folder is empty, remove it...
If .Files.Count = 0 Then If .SubFolders.Count = 0 Then .Delete
End With
End Sub
See this post for a batch example using the forfiles command.

Moving files using VBscript

I am trying to move a group of files with in a group of folders named recup_dir.1 through recup_dir.535 into a single folder so that all the files will be out of the folders and just in the single folder. I know I will need to use a loop to move the files and probably concatenation to go from recup_dir.1 to recup_dir.535 but I just am not that skilled in programming please help!! I just want it to automate the copying and moving of the files rather than do it manually.
Try the following (it assumes that you want to bring the files into the directory that you execute the script from):
Dim filesys, file
Set filesys = CreateObject("Scripting.FileSystemObject")
Dim i
For i = 0 to 535
Dim files
Set files = filesys.GetFolder("recup_dir." & i).Files
For Each file in files
filesys.MoveFile "recup_dir." & i & "\" & file.Name, ".\" & file.Name 'assuming you want all the files to be in the current directory
Next
Next
Of course, please make a backup of all of your folders and files before testing this script.

Resources