使用创建日期复制和重命名文件(批处理脚本)

时间:2016-04-01 15:16:36

标签: batch-file

我有一些格式化为"name.log"

的日志文件

我想将这些文件从一个文件夹复制到另一个文件夹,如

xcopy /y "C:\Folder1" "D:\Folder2"

添加我需要使用创建的原始文件日期(无复​​制文件)重命名文件,以便Folder2中的文本文件类似于"yyyymmddhhmm.log",如果某个文件具有相同的名称(创建日期),它将是覆盖。

我在@Wes Larson的帮助下有一段代码,但是出了点问题。

set Source=C:\Users\user1\Desktop\1
set Dest=C:\Users\user1\Desktop\2
if not exist %Dest% md %Dest%
for /F %%a in ('dir /b "%Source%\*.txt"') do call :Sub %%a
goto :eof

:Sub
set "filename=%1"
for /F %%s in ("%Source%\%1") do  if %%~zs==0 goto :eof
set "datepart="
FOR /F "tokens=1-5 delims=/-: " %%a IN ('dir /tc "%filename%" ^| findstr "%filename%"') DO (
    IF "%%c" neq "" SET "datepart=%%c%%a%%b%%d%%e"
)
FOR /F %%a IN ("%filename%") DO (
    set "NewName=%%~na %datepart%%%~xa"
)
xcopy /y "%Source%\%filename%" "%Dest%\%NewName%*"
GOTO :EOF

问题是,如果我没有将.bat放在与原始文件(Folder1)相同的文件夹中,则某些文件不会更改名称。例如,如果它出来了,某些文件会更改旧名称和一个空格的名称。命令窗口告诉我它在获取创建日期时找不到该文件。这很奇怪,因为有些文件被很好地复制了。

我需要什么来解决这个问题?

1 个答案:

答案 0 :(得分:0)

在我们得到答案之前:在对批处理脚本进行故障排除/调试时,请不要使用@echo off一旦您按照自己的方式工作,它就会很棒想要,但是当你需要逐行查看你的代码是什么时,请注释掉它。此外,您还要打开cmd窗口并从命令行运行脚本,因此只要脚本完成,窗口就不会关闭。

现在开始使用您的代码。这个for循环是您问题的一部分:

FOR /f "tokens=1-3delims=/-:" %%a IN ('dir /tc "%filename%"') DO IF "%%c" neq "" SET "datepart=%%a-%%b-%%c"

首先,您尚未设置%filename%,因此此循环将失败。您可能应该在:Sub中添加一行:

set "filename=%1"

现在,假设%filename%已修复,到此循环结束时,您的%%a%%b%%c变量已设置为命令'dir /tc "%filename%"'的最后一行输出,类似于X Dir(s) XXX,XXX,XXX,XXX bytes free,并且不是您要查找的信息。

所以,相反,您可以稍微调整一下,以便将dir的输出传递给findstr,只查找您要使用的单行,如下所示: / p>

FOR /f "tokens=1-3delims=/-:" %%a IN ('dir /tc "%filename%" ^| findstr "%filename%"') DO (
    IF "%%c" neq "" SET "datepart=%%a-%%b-%%c"
)

但是,您还有另一个问题:%datepart%看起来像MM-DD-YYYY hh。这是因为您将delims从默认值(包括空格和制表符)更改为仅指定的字符。此外,根据您的问题,您还希望将小时和分钟都格式化为" yyyymmddhhmm.log" ,这意味着你也需要接下来的两个令牌。然后你的线就变成了这个:

FOR /f "tokens=1-5 delims=/-: " %%a IN ('dir /tc "%filename%" ^| findstr "%filename%"') DO (
    IF "%%c" neq "" SET "datepart=%%c%%a%%b%%d%%e"
)

接下来,嵌套的for循环会造成混乱,不必要并导致问题:

FOR /f %%a IN ("%filename%") DO FOR /f %%d IN ("%datepart%") DO (
    set NewName="%%~na %%d%%~xa
    xcopy e/d/y "%Source%\%OrgName%" "%Dest%\%NewName%"
)

您已拥有%datepart%变量,并且不需要将其变为for %%d变量之一以便能够引用它。所以当你这样做时会变得更加简单:

FOR /f %%a IN ("%filename%") DO (set "NewName=%%~na %datepart%%%~xa")

另外,由于遇到延迟扩展问题,将xcopy命令排除在循环之外会更简单。

再一次,你有一个你从未设定的变量%OrgName%。幸运的是,这实际上是不必要的,因为您已经将原始文件名捕获为%filename%。因此,过于复杂的嵌套for循环变为:

FOR /f %%a IN ("%filename%") DO (
    set "NewName=%%~na %datepart%%%~xa"
)
echo xcopy e/d/y "%Source%\%filename%" "%Dest%\%NewName%"