更改Windows命令行中时间变量的时间输出以在批处理文件中使用

时间:2018-02-01 08:38:36

标签: batch-file cmd

目标:使用批处理文件将具有特定扩展名的子目录中的文件备份到另一个目录。

forfiles /P C:\Users\user\Desktop\testdest\ -D 3 /C "cmd /c IF @isdir == TRUE rd /S /Q @path" 
mkdir C:\Users\user\Desktop\testdest\%date%
FOR /R C:\Users\user\Desktop\testsrc\ %%A in (*.txt) do (
echo %%A
copy "%%A" "C:\Users\user\Desktop\testdest\%DATE%\%time:~0,2%_%time:~3,2%_%time:~6,2%_%time:~9,2%_%%~nxA
)

我尝试了多种方法来找到使文件名唯一的方法。 遗憾的是,子目录中的文件与其他子目录中的文件具有相同的名称,因此要使它们在目标目录中唯一,它们需要一个使其唯一的前缀或后缀。 尝试了一个计数器变量,但无法弄清楚如何递增它。 我最终尝试使用时间变量,但它似乎在整个批处理文件运行中保持不变。

输出是这样的:

copy "C:\Users\user\Desktop\testsrc\sub\subsub\311.txt" "C:\Users\user\Desktop\testdest\01.02.2018\ 9_24_31_52_311.txt

copy "C:\Users\user\Desktop\testsrc\sub\subsub\312.txt" "C:\Users\user\Desktop\testdest\01.02.2018\ 9_24_31_52_312.txt

当存在多个具有相同名称的文件时,时间输出保持不变,这是一个什么问题。

那么为什么时间输出不会改变毫秒?

4 个答案:

答案 0 :(得分:1)

尝试delayed expansion

setlocal enableDelayedExpansion
forfiles /P C:\Users\user\Desktop\testdest\ -D 3 /C "cmd /c IF @isdir == TRUE rd /S /Q @path" 
mkdir C:\Users\user\Desktop\testdest\%date%
FOR /R C:\Users\user\Desktop\testsrc\ %%A in (*.txt) do (
  echo %%A
  copy "%%A" "C:\Users\user\Desktop\testdest\%DATE%\!time:~0,2!_!time:~3,2!_!time:~6,2!_!time:~9,2!_%%~nxA
)

请注意,%time%在不同的机器上可能会有所不同,因为它依赖于本地设置。

答案 1 :(得分:0)

SETLOCAL ENABLEDELAYEDEXPANSION

FOR /R C:\Users\user\Desktop\testsrc\ %%A in (*.txt) do (
echo %%A
copy "%%A" "C:\Users\user\Desktop\testdest\!DATE!\!time:~0,2!_!time:~3,2!_!time:~6,2!_!time:~9,2!_%%~nxA
)

ENDLOCAL

请使用search工具阅读delayed expansion上的许多文章,了解原因。

答案 2 :(得分:0)

非常感谢@Magoo和@npocmaka

它就像一个魅力。

让我困惑的是,在批量输出中,!时间!变量不会显示为扩展。

例如

的输出
SETLOCAL EnableDelayedExpansion
Set timeexpand=!time:~0,2!_!time:~3,2!_!time:~6,2!_!time:~9,2!
copy "%%A" "C:\Users\user\Desktop\testdest\%DATE%\!timeexpand!_%%~nxA

copy "C:\Users\user\Desktop\testsrc\sub\subsub\331.txt" "C:\Users\user\Desktop\testdest\01.02.2018\!timeexpand!_331.txt

虽然变量没有显示,但是#34;扩展"在copy命令" echo"中,脚本生成的文件名具有正确的时间戳。

为exmaple

10_18_28_59_1.txt
10_18_28_60_2.txt
10_18_28_61_3.txt

我的最终脚本如下所示:

eventcreate /L APPLICATION /SO backup /T INFORMATION /ID 337 /D "Starting copy of database files"
SETLOCAL EnableDelayedExpansion
forfiles /P D:\backup\bckup\ -D 3 /C "cmd /c IF @isdir == TRUE rd /S /Q @path" 
mkdir D:\backup\bckup\%date%
FOR /R D:\dbs %%F in (*.mdf) do ( 
timeout 1
Set timeexpandmdf=!time:~0,2!_!time:~3,2!_!time:~6,2!_!time:~9,2!
copy "%%F" "D:\backup\bckup\%date%\%%~nF_!timeexpandmdf!_%%~xF" 
)
FOR /R D:\dbs %%F in (*.ldf) do (
timeout 1
Set timeexpandldf=!time:~0,2!_!time:~3,2!_!time:~6,2!_!time:~9,2!
copy "%%F" "D:\backup\bckup\%date%\%%~nF_!timeexpandldf!_%%~xF" 
)
echo %DATE% %time% >> d:\backup\file.age
ENDLOCAL
eventcreate /L APPLICATION /SO backup /T INFORMATION /ID 337 /D "copy of database files done"

答案 3 :(得分:0)

这在PowerShell中对我来说更清晰。如果您确信将使用正确的名称复制正确的文件,请从-WhatIf cmdlet中删除Copy-Item

在PowerShell中执行此操作可以减轻您必须考虑本地日期和时间格式所需的内容。

$testsrc = 'C:\src\t\ct1'
$testdest = 'C:\src\t\ct2'
$thedate = Get-Date -Format 'yyyyMMdd'

Remove-Item -Path $testdest\* -Recurse
New-Item -Path $testdest -Name $thedate -ItemType 'directory' | Out-Null
Get-ChildItem -Path $testsrc -Recurse -Filter *.txt |
    ForEach-Object { Copy-Item -Path $_.FullName -Destination "$testdest\$thedate\$(Get-Date -Format 'HH_mm_ss_ffff_')$($_.Name)" -WhatIf }

我注意到的一点是,毫秒值并不总是经常变化,因为每个文件都有不同的时间戳。如果您在源的两个不同目录中具有相同名称的文件,则可能会出现问题。