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

Posted

技术标签:

【中文标题】使用创建日期复制和重命名文件(批处理脚本)【英文标题】:copy and rename file with create date (Batch script) 【发布时间】:2016-04-01 15:16:35 【问题描述】:

我有一些格式如下的日志文件"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) 相同的文件夹中,则某些文件不会更改名称。例如,如果某些文件用旧名称和一个空格更改名称,则某些文件会更改名称。命令窗口告诉我它在获得创建日期时找不到该文件。这很奇怪,因为有些文件复制得很好。

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

【问题讨论】:

当问题陈述只是“它不起作用”时,很难诊断问题。请edit您的问题更完整地描述您预期会发生什么以及这与实际结果有何不同。请参阅 How to Ask 以获取有关什么是好的解释的提示。 你好,我理解你,但问题是我没有结果,所以我确定我的代码是错误的。当我执行 bat 时,一个命令窗口打开然后关闭,我什么也看不到。 调试的简单方法是暂时删除@echo off,然后进入cmd.exe 并调用您的批处理文件。 cmd.exe 应该在大多数错误上保持打开状态,并且可以让您查看是否正在发生语法错误或错误的退出位置。 【参考方案1】:

在我们得到答案之前:在对批处理脚本进行故障排除/调试时,不要使用@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,只查找您想要使用的一行,如下所示:

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%"

【讨论】:

我有一些文件没有在文件夹 2 上写日期的问题。我从命令窗口运行脚本,我可以看到消息“它找不到文件”。我在下面写了完整的问题。非常感谢。

以上是关于使用创建日期复制和重命名文件(批处理脚本)的主要内容,如果未能解决你的问题,请参考以下文章

Windows批处理脚本实现批量复制文件并重命名

使用文件夹名称复制和重命名文件的批处理文件

查找和重命名没有扩展名的文件?

使用批处理解压缩和重命名文件 (Windows)

如何用批处理命令创建一个以“日期”+读取粘贴板数据命名的文件夹?

sh 从命令行复制和重命名文件(用于NPM脚本)。需要https://github.com/mysticatea/cpx