1

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

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

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

4 回答 4

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
)
于 2013-02-10T16:14:25.587 回答
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循环体内的实际值。如果您不知道,%当在同一命令块中设置和检索值时,块命令中环境变量的“正常”( ) 扩展不起作用。这就是延迟扩展派上用场的地方。您首先需要启用它,然后使用不同的扩展语法(!s 而不是%)。

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

于 2013-02-10T11:40:10.627 回答
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"

希望这可以帮助。

于 2013-02-10T07:16:53.053 回答
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"
    }
}
于 2017-08-19T15:24:31.447 回答