如何根据文件的创建日期来重命名文件?问:嗨,Scripting Guy!我的文件夹中包含一些日志文件。我想根据文件的创建日期来重命名每个文件;例如,如果文件是在 2004 年 12 月 1 日创建的,我想将其重命名为 20041201.log。我能做到吗? -- CK 答:嗨,CK。听着,如果说到脚本,就没有什么是做不到的。(当然了,人力所不能及的事情除外。)通常,在 WMI 脚本中很难解决日期问题,但就您说的问题而言,实际上,可以使用 WMI 日期格式轻松地 完成此项任务。 为了帮助说明是如何实现这一功能的,我们将此项任务分为两个部分。首先,我们如何列出文件夹中的所有文件及其创建日期?一种方法是使用类似下面的脚本: strComputer = "." Set objWMIService = GetObject("winmgmts\\" & strComputer & "\root\cimv2") Set FileList = objWMIService.ExecQuery _ ("ASSOCIATORS OF {Win32_Directory.Name=‘C:\Logs‘} Where " _ & "ResultClass = CIM_DataFile") For Each objFile In FileList Wscript.Echo objFile.CreationDate Next 在此脚本中,我们绑定到 WMI 服务,然后使用关联查询来返回文件夹 C:\Logs 中所有文件的集合。如果您不熟悉关联查询,切记它们具备的功能与其名字的含义大致相同:它们提供了一种将两个单独 WMI 类关联在一起的方法,此处为 Win32_Directory 和 CIM_DataFile。实际效果是,可使我们获取关联文件夹中所有文件的集合。 在获取所有文件后,我们只需创建一个 For-Each 循环,然后回显每个文件的“CreationDate”属性值即可。因为 WMI 使用 UTC(通用时间协调)格式,所以我们将获取类似下面的值: 20041201202723.695209-480 不错,看起来有点怪怪的,但您猜怎么样:前八个字符恰巧对应于年、月和日,这正是您要用作文件名的值。您想要得到类似于 20041201 的文件名吗?看一下 UTC 日期中的前八个字符:20041201202723.695209-480。这正在您想到的东西。 事实上,要获取文件名,我们只需使用 VBScript 的 Left 函数获取 UTC 日期中的前八个字符即可。以下修改后的脚本提取前八个字符,将它们存储在名为 strDate 的变量中,然后回显该 值: strComputer = "." Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") Set FileList = objWMIService.ExecQuery _ ("ASSOCIATORS OF {Win32_Directory.Name=‘c:\Logs‘} Where " _ & "ResultClass = CIM_DataFile") For Each objFile In FileList strDate = Left(objFile.CreationDate, 8) Wscript.Echo strDate Next 第一步到此为止。现在,我们开始介绍第二步,也是最后一步:重命名每个文件。让我们看一下该脚本,然后再解释它是如何工作的: strComputer = "." Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") Set FileList = objWMIService.ExecQuery _ ("ASSOCIATORS OF {Win32_Directory.Name=‘C:\Logs‘} Where " _ & "ResultClass = CIM_DataFile") For Each objFile In FileList strDate = Left(objFile.CreationDate, 8) strNewName = objFile.Drive & objFile.Path & strDate & "." & "log" errResult = objFile.Rename(strNewName) Next 此处的难点是构造新的文件名。在使用 WMI 重命名文件时,不能只指定一个新名称;例如,不能将文件“Wednesday.log”直接重命名为“20041201.log”。而是必须指定整个路径并重命名文件“C:\Logs\20041201.log”。这就是下面这行代码所完成的操作: strNewName = objFile.Drive & objFile.Path & strDate & ".log" 我们此处所执行的操作是将文件所在的驱动器(“C:”)、该驱动器上的文件夹路径(“\Logs\”)、文件的新名称(“20041201”)、变量 strDate 的值以及新文件的扩展名(“.log”)合并在一起。将所有这些组合在一起,就会得到“C:\Logs\20041201.log”,这正是我们要为文件指定的完整路径。现在,我们只需调用 Rename 方法并更改文件名即可。 顺便说一下,我们知道仅仅为重命名文件而必须提供完整路径有一点怪怪的。如果说有什么好的一面的话,那就是可以使用这种相同的方法将文件移到另一个文件夹中。例如,假定您不仅想重命名文件,而且还想将它们移到名为 C:\Backups 的文件夹中。在这种情况下,可以使用类似下面的脚本,它将当前文件路径(“\Logs\”)替换为新的路径(“\Backups\”)。运行该脚本,这样不仅会重命名文件,而且还会将文件移到 C:\Backups: strComputer = "." Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") Set FileList = objWMIService.ExecQuery _ ("ASSOCIATORS OF {Win32_Directory.Name=‘C:\Logs‘} Where " _ & "ResultClass = CIM_DataFile") For Each objFile In FileList strDate = Left(objFile.CreationDate, 8) strNewName = objFile.Drive & "\Backups\" & strDate & ".log" errResult = objFile.Rename(strNewName) Next 我们介绍的脚本存在的唯一问题是,如果文件具有相同的创建日期,它就会遇到麻烦了;毕竟,脚本将试图创建两个具有相同名称的文件,例如,20041201.log,而文件系统不希望同一文件夹中包含两个同名的文件。如果出现这种问题,可以使用以下示例脚本,它在实际重命名文件之前,先检查文件名是不是唯一的。例如,假定文件夹中已包含一个名为 20041201.log 的文件。如果发生这种情况,此脚本(今天我们不会详细介绍这个脚本)将创建一个新的文件名:20041201_2.log,并检查该 文件是否已存在。如果文件存在,则它尝试命名为 20041201_3.vbs,然后继续尝试,直到创建一个唯一的名称。此时,它将重命名该文件: strComputer = "." Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") Set FileList = objWMIService.ExecQuery _ ("ASSOCIATORS OF {Win32_Directory.Name=‘c:\Logs‘} Where " _ & "ResultClass = CIM_DataFile") For Each objFile In FileList strDate = Left(objFile.CreationDate, 8) strNewName = objFile.Drive & objFile.Path & _ strDate & "." & "log" strNameCheck = Replace(strNewName, "\", "\\") i = 1 Do While True Set colFiles = objWMIService.ExecQuery _ ("Select * from Cim_Datafile Where Name = ‘" & strNameCheck & "‘") If colFiles.Count = 0 Then errResult = objFile.Rename(strNewName) Exit Do Else i = i + 1 strNewName = objFile.Drive & objFile.Path & _ strDate & "_" & i & "." & "log" strNameCheck = Replace(strNewName, "\", "\\") End If Loop Next 的确,有一点复杂,这就是为什么改日再介绍该脚本的原因。您也想休息一下,对吧? |
|