将文件从文件夹移动并重命名为.bat文件,并在开头添加修改日期

时间:2013-02-10 06:40:30

标签: batch-file rename move last-modified

我花了很多时间试图解决这个问题而没有运气。

方案: 有多个不同的文件名,但文件夹中的扩展名相同。在Windows Server 2008 64bit上。 想要使用计划批处理作业将它们移动到另一个文件夹。 。蝙蝠。在移动过程中,我想重命名它们以包括它们的最后修改日期。我想尝试这种格式:

yyyymmddhhmmss-name.zip

我查看了PowerShell和for命令,但无法解决问题。

我找到了这个3行代码,它在Windows 7上运行良好,但在Windows Server 2008上运行不正确。

@echo off
set Date=%date:~10,4%%date:~4,2%%date:~7,2%
move d:\Test\*.zip d:\Test1\*%Date%.zip

在服务器上,它无法理解*%Date%。我删除*后,就可以了。我尝试了不同的引号等变化但不起作用。我知道日期不是我追求的解决方案,但是如果我不能让这条简单的线路起作用,那么其余部分也无关紧要。

哦,抵消确实有效,所以我得到了yyyymmdd的日期。 我已经避免使用PowerShell,因为我对它不好,我也看了VBS。但这不是强项。有人可以帮忙吗?

我知道很多问题都是类似的,但没有什么能与我想做的完全匹配。

4 个答案:

答案 0 :(得分:1)

WMIC可用于将最后修改的时间戳记作为小数秒精度。前14个字符的格式与您正在寻找的格式完全相同。

这是一个快速解决方案,完全符合您的要求:

@echo off
for /f "skip=1 delims=" %%A in (
  'wmic datafile where "drive='d:' and path='\\test\\' and extension='zip'" get lastModified^,name'
) do for /f "tokens=1*" %%B in ("%%A") do (
  set "timestamp=%%B"
  set "file=%%~fC"
  set "fileName=%%~nxC"
  setlocal enableDelayedExpansion
  move "!file!" "d:\test1\!timestamp:~0,14!-!fileName!"
  endlocal
)

如果你想改变要求,上面的内容很挑剔。如果你不小心,你的WMIC命令可能会花费很长时间,并且有些文件掩码根本无法用WMIC模拟。

下面是一个非常方便的慢得多的解决方案。您将源文件掩码和目标路径作为参数传递。假设脚本名为“addTimeStamp.bat”,那么您将使用addTimeStamp "d:\test\*.zip" "d:\test1"

@echo off
setlocal disableDelayedExpansion
set "filePath="
if "%~2" neq "" for /f "eol=: delims=" %%F in ("%~2\") do set "filePath=%%~fF"
for %%F in (%1) do (
  set "file=%%~fF"
  set "fileName=%%~nxF"
  setlocal enableDelayedExpansion
  for /f "skip=1" %%A in (
    'wmic datafile where "name='!file:\=\\!'" get lastModified'
  ) do for /f %%A in ("%%A") do (
    set "timestamp=%%A"
    move "!file!" "!filePath!!timestamp:~0,14!-!fileName!
  )
  endlocal
)

答案 1 :(得分:0)

您可以通过使用wmic命令来完成此操作。这使您可以获得当前日期和时间,而不受区域设置的影响。同时它也可以帮助您重命名zip文件。

@echo off
SETLOCAL EnableDelayedExpansion

for /f "skip=1 tokens=1-6 delims= " %%a in ('wmic path Win32_LocalTime Get Day^,Hour^,Minute^,Month^,Second^,Year /Format:table') do (
    IF NOT "%%~f"=="" (
        set /a FormattedDate=10000 * %%f + 100 * %%d + %%a
        set /a FormattedTime=%%b * 10000 + %%c * 100 + %%e
    )
)

for /f %%f in ("D:\Test*.zip") DO set filename=%%~nf

move "D:\Test*.zip" "D:\%FormattedDate%%FormattedTime%-%filename%.zip"

希望这有帮助。

答案 2 :(得分:0)

您可以使用FOR循环并将~t修饰符应用于循环变量以访问每个文件的上次修改时间戳。在使用MOVE命令实际使用之前,您需要将原始时间戳值调整为必要的格式。这是一个如何做到这一点的例子:

@ECHO OFF
FOR %%I IN ("D:\Test\*.zip") DO (
  SET lmdate=%%~tI
  SETLOCAL EnableDelayedExpansion
  SET lmdate=!lmdate:~6,4!!lmdate:~3,2!!lmdate:~0,2!!lmdate:~11,2!!lmdate:~14,2!
  MOVE "%%I" "D:\Test1\!lmdate!-%%~nxI"
  ENDLOCAL
)

应该注意的是,带有~t修饰符的循环变量返回的时间戳的精度限制为几分钟,所以如果您真的需要秒,正如您的帖子所暗示的那样,这可能不是为您提供解决方案。

无论如何,这就是剧本的运作方式。

在每次迭代时,都会为%%I循环变量分配一个文件名。 ~t修饰符指示变量解析为相应文件的上次修改时间戳。

首先使用lmdate(第一个%%~tI语句)返回的时间戳初始化SET lmdate变量,然后重新排列该值以适应yyyyMMddHHmm格式(第二个SET lmdate声明)。请注意,由于原始时间戳的格式取决于系统的语言环境,因此您可能需要修改第二个SET语句以适应您的特定系统。以上脚本采用以下格式:

dd.MM.yyyy HH:mm

访问循环体内的实际SETLOCAL EnableDelayedExplansion值需要您在上面看到的lmdate语句。如果您不知道,当在同一命令块中设置和检索值时,块命令中的“正常”(%)扩展环境变量将不起作用。这就是延迟扩张派上用场的地方。您首先需要启用它,然后使用不同的扩展语法(!而不是%)。

您可以看到脚本中使用的其他修饰符,即~n~x~nx一起使用时)。前者仅解析为文件名(无路径或扩展名),后者仅解析为扩展名。还有其他修饰符,它们记录在FOR命令的内置帮助(FOR /?)中。

答案 3 :(得分:0)

我已经制作了一个PowerShell脚本来完全按照你想要的那样。

脚本: -

$src=""      # Source Path of Files to move
$trg=""      # Destination folder
$a=Get-ChildItem $SRC 
IF($a)
{
    for($i=0; $i -le ($a.Count - 1); $i++)
    {
        $fileName=$a[$i].Name
        $fileNameWithoutExtension=$fileName -replace ".zip", ""
        $dirPath=$a[$i].DirectoryName
        $lastModifiedDate=$a[$i].LastWriteTime
        $LMFDate=($lastModifiedDate).ToString("yyyy-MM-dd-hh-mm-ss");
        $srcFile="$dirPath\$fileName"
        move-Item $srcFile "$trg\$LMFDate-$fileName"
    }
}