File rename utility
Welcome to the file rename utility
Purpose
This utility renames all files of a given directory so that the last modified date of each individual file is added as prefix at the very beginning of the filename.
The program is coded in TCL/TK and compiled to an executable so that it can be used “out of the box” and without the need to install something extra.
Example:
current_directory:
------------------
demo01.txt --> 20-03-01_demo01.txt
demo02.txt --> 20-03-02_demo01.txt
demo03.txt --> 20-03-03_demo01.txt
|-------|
|
| **date prefix** added by the filerename
| utility according to the last modified date
| of each individual file
Once files are renamed this way, the filename can be used to specify sort order (instead of sorting by date). The sort order keeps the same throughout the lifetime of a file, regardless if the modification time-stamp might change in the future.
Usage
Under windows you can either use the command dialog window to start “filerenamer” executable with one argument specifying a directory or: just use file explorer to drag and drop a directory onto the “filerenamer.exe” icon (my preferred option)!
Files in the directory which already have the date prefix in the name, are skipped and won’t get renamed a 2nd time.
Spaces in filenames are automatically converted to dash char’s.
Source code
# file rename utility
# set dir [file dirname [info script]]
# show console (under windows only)
catch {
package require Tk
wm withdraw .
console show
console eval {wm protocol . WM_DELETE_WINDOW {exit 0}}
puts \
"
Welcome to the file rename utility v0.1
---------------------------------------
Purpose:
This utility renames all files of a given directory
so that the last modified date of each individual file
is added at the very beginning of the filename.
Once files are renamed this way, they can be sorted
(same as sort by date) and the sort order keeps the same
throughout the lifetime of a file, regardless
if the modification time might change or not.
Files in the directory which already have the date prefix
in the name, are skipped and won't get renamed a 2nd time.
Spaces in filenames are automatically converted to dash char's.
Usage:
Under windows you can either use the command dialog window
to start filerenamer executable with one argument
specifying a directory or
just drag and drop a directory onto the filerenamer icon!
-------------
Copyright:
(c) 2020, Johann Oberdorfer - Engineering Support | CAD | Software
johann.oberdorfer \[at\] gmail <dot> com
www.johann-oberdorfer.eu
This source file is distributed under the BSD license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the BSD License for more details.
"
}
# https://wiki.tcl-lang.org/page/Time+and+date+validator
# "5:13:52" (%T) => 1
# "1/2/2003" (%D) => 1
proc timevalidate {format str} {
# Start with a simple check: If the string cannot be parsed against
# the specified format at all it's definitely wrong
if {[catch {clock scan $str -format $format} time]} {
return 0
}
# Create a table for translating the supported clock format specifiers
# to scan format specifications
set map {%a %3s %A %s %b %3s %B %s %d %2d %D %2d/%2d/%4d
%e %2d %g %2d %G %4d %h %s %H %2d %I %2d %j %3d
%J %d %k %2d %l %2d %m %2d %M %2d %N %2d %p %2s
%P %2s %s %d %S %2d %t \t %T %2d:%2d:%2d %u %1d
%V %2d %w %1d %W %2d %y %2d %Y %4d %z %4d %Z %s
}
# Build the scan format string out of the clock format string
set scanfmt [string map $map $format]
# Recreate the time string from the seconds value
set tmp [clock format $time -format $format]
# Scan both versions of the string representation
set list1 [scan $str $scanfmt]
set list2 [scan $tmp $scanfmt]
# Compare all elements as numbers and strings
foreach n1 $list1 n2 $list2 {
if {$n1 != $n2 && ![string equal -nocase $n1 $n2]} {return 0}
}
# Declare the time string valid since all elements matched
return 1
}
set current_dir [lindex $argv 0]
# set current_dir "C:/_Projekte_SoftwareEntwicklung/12_TclTK_StarterPackage/filerename/test"
set DELIM "_"
set DATEFMT "%y-%m-%d"
if { ![file exists $current_dir] } {
puts \
"
***Error:
No argument given to function.
Please specify a directory name and try again!
"
} else {
set file_list [glob -nocomplain -type f [file join $current_dir "*"]]
set tmp_list [list]
foreach item $file_list {
# puts "$item - [clock format [file mtime $item] -format $DATEFMT]"
set fdir [file dirname $item]
set fname [file tail $item]
set mtime [clock format [file mtime $item] -format $DATEFMT]
set fname [string trim [string map {" " "-"} $fname]]
set new_filename "${mtime}${DELIM}${fname}"
# puts $new_filename
# check out, if the date prefix is already part of the filename:
# yy-mm-dd
set str [string range $fname 0 [expr {[string length $DATEFMT] -1}]]
# puts "$str : [timevalidate $DATEFMT $str]"
if {![timevalidate $DATEFMT $str]} {
if {[catch {file rename $item [file join $fdir $new_filename]} errmsg] == 0} {
lappend tmp_list $new_filename
} else {
puts $errmsg
}
}
}
if {[llength $tmp_list] == 0} {
puts "No files renamed - nothing more to do.\n"
} else {
puts "Files renamed to:\n"
foreach f [lsort -dictionary $tmp_list] {
puts $f
}
puts \
"\nDone ([llength $tmp_list] / [llength $file_list]) file(s) successfully renamed."
}
}
Download
The actual package can be downloaded directly from the link provided below.
The zip file includes the source code and as well a pre-compiled binary for windows.
The execute-able does not require any additional software or library to be installed.
File name: | Size / byte: | |
---|---|---|
filerename0.1.zip | 66197905 |
and in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the BSD License for more details.
Future improvements
… would be:
a graphical dialog with drag&drop capability (like Markdown2Go dialog) which allows to rename not only files but also directories
possibility to remove the datum prefix
possibility to specify the format of the prefix
Add on - a Similar function implemented with VBS
In situations, where here is no TCLSH interpreter installed or it is not possible to download and/or start an executable due to security policies, here is an implementation of basically the same functionality but in plain VBS code.
Language: VBS - Visual Basic Script Language
' -------------------------------------------------------------------
' --- add-timestamp-for-all-files-in-a-folder.vbs
' -------------------------------------------------------------------
' -----------------------------------------------------------------------------
' (c) 2021, Johann Oberdorfer - Engineering Support | CAD | Software
' johann.oberdorfer [at] gmail.com
' www.johann-oberdorfer.eu
' -----------------------------------------------------------------------------
' This source file is distributed under the BSD license.
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY; without even the implied warranty of
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
' See the BSD License for more details.
' -----------------------------------------------------------------------------
' Purpose:
' VBS script to add a time stamp to all files of a given folder
' files which already have a time stamp, are skipped
' -------------------------------------------------------------------
' Change history:
' 21-07-22, Johann, Initial release
' -------------------------------------------------------------------
Const TITLE = "Add Timestamp Function"
' -----------------------
' drag and drop arguments
' -----------------------
Set objArgs = WScript.Arguments
' For i = 0 to objArgs.Count - 1: WScript.Echo objArgs(i): Next
For i = 0 to objArgs.Count - 1
msg = msg + objArgs(i) + vbNewLine
Next
If (objArgs.Count = 0) Then
MsgBox _
"No arguments given to the function." _
+ vbNewLine + vbNewLine _
+ "Usage: Select a directory and drag&drop it onto the program's icon.", _
+ vbInformation + vbOKOnly, TITLE + ", Information: "
WScript.Quit
End If
Select Case MsgBox( _
"The following arguments have been passed to the function:" _
+ vbNewLine + vbNewLine _
+ msg _
+ vbNewLine _
+ "Would you like to continue?", _
vbInformation + vbOKCancel, TITLE + ", Question: ")
Case 1: ' O.K. pressed
Case 2: WScript.Quit
End Select
Function CreateTimestamp (date_str)
mm = Month(date_str)
dd = Day(date_str)
yy = Right (Year(date_str), 2) ' only take 2 digits
If Len(mm) < 2 Then mm = "0" & mm
If Len(dd) < 2 Then dd = "0" & dd
CreateTimestamp = yy & "-" & mm &"-"& dd
End Function
' --------------
' here we go ...
' --------------
Set fs = CreateObject("Scripting.FileSystemObject")
For i = 0 to objArgs.Count - 1
folder_name = objArgs(i)
Set dir = fs.GetFolder(folder_name)
' timestamp = CreateTimestamp(Now())
cnt = 0
For Each f In dir.Files
file_name = f.Name
base_name = fs.GetBaseName(file_name)
ext = fs.GetExtensionName(file_name)
' timestamp = CreateTimestamp(f.DateCreated)
timestamp = CreateTimestamp(f.DateLastModified)
If (InStr(file_name, timestamp) = 0) Then
f.Name = timestamp & "-" & base_name & "." & ext
cnt = cnt + 1
End If
Next
If (cnt = 0) Then
MsgBox _
"No Files renamed." + vbNewLine _
+ "You might want to specify a different directory and try again.", _
+ vbInformation + vbOKOnly, TITLE + ", Information: "
Else
MsgBox _
CStr(cnt) + " File(s) successfully renamed." + vbNewLine _
+ "You might want check the result or continue with another directory.", _
+ vbInformation + vbOKOnly, TITLE + ", Information: "
End If
Next
Copy & paste this code into a file, save it and use the explorer to drag and drop a directory onto the program’s file icon. Files are instantly renamed as described, so you would probably want to backup your data beforehand.