Created
September 15, 2012 20:50
-
-
Save hanji/3729693 to your computer and use it in GitHub Desktop.
(WSH) file timestamp manipulation utility
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// touch.js --- file timestamp manipulation utility (like *nix touch) | |
// (c) Copyright 2012, Ji Han (hanji <at> outlook <dot> com) | |
// you are free to distribute it under the BSD license. | |
(function(){ | |
if (WScript.Arguments.Length == 0){ | |
// this script works for files, but not folders. (you need win32api to do that.) | |
// plus, there's no '-a' or '-m' options; it only touches the mtime. | |
WScript.Echo('touch [-c] [-r <reference_file> | -t <timestamp>] <files>'); | |
WScript.Quit(1); | |
} | |
var convertDateToModifyDate = function(d){ | |
return (d.getMonth() + 1) + '/' + d.getDate() + '/' + d.getFullYear() | |
+ ' ' + ((d.getHours() + 11) % 12 + 1) + ':' + ('00' + d.getMinutes()).slice(-2) + ':' + ('00' + d.getSeconds()).slice(-2) | |
+ ' ' + (d.getHours() < 12 && 'AM' || 'PM'); | |
} | |
// parse string '[[CC]YY]MMDDhhmm[.SS]' as date and time | |
var parseTimestampString = function(s){ | |
var a, b, c; | |
if (!(a = s.match(/^(\d+)(\.\d+)?$/))){ return null } // a[1]: CCYYMMDDhhmm, a[2]: .SS or undefined | |
if (!(b = a[1].match(/^(\d{4}|\d{2})?(\d{8})$/))){ return null } // b[1]: CCYY or undefined, b[2]: MMDDhhmm | |
c = b[2].match(/../g); // c[0]: MM, c[1]: DD, c[2]: hh, c[3]: mm | |
var x = (new Date()).getFullYear(); | |
// 'if (b[1] === undefined)' should have worked. but... it is broken. | |
// 'parseInt(undefined)' would yield NaN, which evaluates to false in an 'if' clause. | |
var y = parseInt(b[1], 10); | |
if (!y){ y = x } else if (y < 100){ y = x - x % 100 + y } | |
// Gotcha: must specify radix 10, otherwise '09' would be parsed as zero. | |
var m = parseInt(c[0], 10), d = parseInt(c[1], 10), h = parseInt(c[2], 10); | |
return m + '/' + d + '/' + y | |
+ ' ' + ((h + 11) % 12 + 1) + ':' + c[3] + ':' + (a[2] || '00').slice(-2) | |
+ ' ' + (h < 12 && 'AM' || 'PM'); | |
} | |
var fso = new ActiveXObject('Scripting.FileSystemObject'); | |
var shell = new ActiveXObject('Shell.Application'); | |
// expand wildcards (asterisk [*] and question mark [?]) | |
// given path may be relative, and may contain environment variables. | |
// but wildcards only work for the filename part of a path. | |
// return an array of full paths of matched files. | |
// {{{ | |
var expandWildcards = function(f){ | |
var pattern = fso.GetFileName(f); | |
// escape regex metacharacters (except \, /, * and ?) | |
// \ and / wouldn't appear in filename | |
// * and ? are treated as wildcards | |
pattern = pattern.replace(/([\[\](){}^$.+|-])/g, '\\$1'); | |
pattern = pattern.replace(/\*/g, '.*'); // * matches zero or more characters | |
pattern = pattern.replace(/\?/g, '.'); // ? matches one character | |
pattern = pattern.replace(/^(.*)$/, '\^$1\$'); // matches the whole filename | |
var re = new RegExp(pattern, 'i'); // case insensitive | |
var folder = shell.NameSpace(fso.GetParentFolderName(fso.GetAbsolutePathName(f))); | |
var l = []; | |
for (var i = 0; i < folder.Items().Count; ++i){ | |
var filespec = folder.Items().Item(i).Path; | |
var filename = fso.GetFileName(filespec); | |
if (filename.match(re)){ l.push(filespec) } | |
} | |
return l; | |
} | |
// }}} | |
var modifyDateOfFolderItem = function(it){ | |
return shell.NameSpace(fso.GetParentFolderName(fso.GetAbsolutePathName(it))).ParseName(fso.GetFileName(it)).ModifyDate; | |
} | |
var args = []; | |
var options = {}; | |
for (var i = 0; i < WScript.Arguments.Length; ++i){ | |
if (WScript.Arguments(i).substring(0, 1) != '-'){ | |
args.push(WScript.Arguments(i)); | |
} else if (WScript.Arguments(i) == '-r'){ | |
options['reference_file'] = WScript.Arguments(++i); | |
} else if (WScript.Arguments(i) == '-t'){ | |
options['timestamp'] = WScript.Arguments(++i); | |
} else if (WScript.Arguments(i) == '-c'){ | |
options['creative'] = false; | |
} else if (WScript.Arguments(i) == '--'){ | |
continue; | |
} else { | |
WScript.Echo('invalid option \'' + WScript.Arguments(i) +'\''); | |
WScript.Quit(1); | |
} | |
} | |
var mTime; | |
if (options['timestamp']){ | |
mTime = parseTimestampString(options['timestamp']); | |
} | |
else if (options['reference_file']){ | |
var it = options['reference_file']; | |
if (!(fso.FileExists(it) || fso.FolderExists(it))){ | |
WScript.Echo('reference file \'' + it +'\' not found.'); | |
WScript.Quit(1); | |
} | |
mTime = modifyDateOfFolderItem(it); | |
} | |
else { | |
mTime = convertDateToModifyDate(new Date()); | |
} | |
for (var i = 0; i < args.length; ++i){ | |
var it = args[i]; | |
if (it.match(/[*?]/)){ | |
var l = expandWildcards(it); | |
}else{ | |
var l = [it]; | |
} | |
for (var j = 0; j < l.length; ++j){ | |
var it = l[j]; | |
if (!(fso.FileExists(it) || fso.FolderExists(it))){ | |
if (options['creative'] === false){ | |
WScript.Echo('file \'' + it +'\' not found.'); | |
continue; | |
} else { | |
fso.CreateTextFile(it); | |
} | |
} | |
//modifyDateOfFolderItem(it) = mTime; //oops... not an lvalue. | |
shell.NameSpace(fso.GetParentFolderName(fso.GetAbsolutePathName(it))).ParseName(fso.GetFileName(it)).ModifyDate = mTime; | |
} | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment