【问题标题】:Move and rename files from folder to folder as a .bat file and adding modified date at beginning将文件从文件夹移动和重命名为 .bat 文件,并在开头添加修改日期
【发布时间】:2013-01-25 13:34:57
【问题描述】:

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

场景: 文件夹中有多个不同的文件名,但扩展名相同。在 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。但这不是强项。有人可以帮忙吗?

我知道有很多类似的问题,但没有什么完全符合我想要做的。

【问题讨论】:

  • 您说您想添加文件的最后修改数据和时间,但您的代码使用当前日期和时间。你真正想要哪个?

标签: batch-file rename move last-modified


【解决方案1】:

您可以通过使用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"

希望这会有所帮助。

【讨论】:

  • 哇,回复太快了!
  • 我在bat文件中添加了代码并修改为指向不同的目录,但是失败了。得到与我 14 小时前收到的相同的错误。即:文件名、目录名或卷标语法不正确。有趣的是,您的代码以及当我输入它时在移动命令中的单词 Test 之后缺少“\”。还有其他地方没有吗?
  • 啊,但它也没有修改时间。不过我喜欢你所做的。
【解决方案2】:

您可以使用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 /?) 中。

【讨论】:

  • 我很高兴只需几分钟而不是几秒钟。我在文件修改时间戳后将其命名。我将此脚本粘贴到 bat 文件中运行它,但得到通常的语法错误。我没有收到任何错误代码。我错过了什么吗?
  • 你可能是,除非我有。您能否详细说明语法错误的确切位置?也许您可以在不关闭回显的情况下运行脚本以查看违规行?我目前看不到任何问题,但我仍在调查。
  • 我发布的脚本中有错字。请立即尝试。
  • 你好安德烈。同样的问题。我已将脚本粘贴到 move.bat 文件中。我已经删除了 echo 语句。我仍然得到:命令的语法不正确。在windows 2008 server 64bit下运行。
  • 是的,请问行被绊倒了?你能发布确切的行吗?
【解决方案3】:

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
)

【讨论】:

    【解决方案4】:

    我已经制作了一个 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"
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-27
      • 1970-01-01
      • 2016-05-07
      • 2014-05-27
      相关资源
      最近更新 更多