Batch file 复制并重命名具有创建日期的文件(批处理脚本)

Batch file 复制并重命名具有创建日期的文件(批处理脚本),batch-file,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:\Us

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


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

在我们得到答案之前:在对批处理脚本进行故障排除/调试时,不要使用
@echo off
一旦它按您想要的方式工作,这将非常好,但是当您需要逐行查看代码的执行情况时,请将其注释掉。此外,您还需要打开一个cmd窗口并从命令行运行脚本,这样脚本完成后窗口不会立即关闭

现在开始你的代码。此
for
循环是问题的一部分:

首先,您尚未设置
%filename%
,因此此循环将失败。您的
:Sub中可能应该有这样一行:

set "filename=%1"
FOR /f "tokens=1-3delims=/-:" %%a IN ('dir /tc "%filename%" ^| findstr "%filename%"') DO (
    IF "%%c" neq "" SET "datepart=%%a-%%b-%%c"
)
FOR /f %%a IN ("%filename%") DO (set "NewName=%%~na %datepart%%%~xa")
现在,假设
%filename%
是固定的,在该循环完成时,您的
%a
%b
%c
变量已设置为命令
'dir/tc”%filename%'
输出的最后一行中的值,这类似于
X dir(s)XXX,XXX,XXX,XXX,XXX,XXX,XXX,XXX字节自由
,这不是你要找的信息

因此,您可以稍微调整它,以便将
dir
的输出通过管道传输到
findstr
,只查找您想要使用的一行,如下所示:

set "filename=%1"
FOR /f "tokens=1-3delims=/-:" %%a IN ('dir /tc "%filename%" ^| findstr "%filename%"') DO (
    IF "%%c" neq "" SET "datepart=%%a-%%b-%%c"
)
FOR /f %%a IN ("%filename%") DO (set "NewName=%%~na %datepart%%%~xa")
但是,您还有另一个问题:您的
%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 /f %%a IN ("%filename%") DO (
    set "NewName=%%~na %datepart%%%~xa"
)
echo xcopy e/d/y "%Source%\%filename%" "%Dest%\%NewName%"
接下来,嵌套的
for
循环令人困惑、不必要,并且会导致问题:

您已经有了
%datepart%
变量,无需将其转换为
for
%d
变量中的一个变量即可引用它。因此,当您这样做时,它会变得简单得多:

set "filename=%1"
FOR /f "tokens=1-3delims=/-:" %%a IN ('dir /tc "%filename%" ^| findstr "%filename%"') DO (
    IF "%%c" neq "" SET "datepart=%%a-%%b-%%c"
)
FOR /f %%a IN ("%filename%") DO (set "NewName=%%~na %datepart%%%~xa")
此外,由于您会遇到延迟扩展问题,因此将
xcopy
命令从循环中删除更简单

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

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"
)
echo xcopy e/d/y "%Source%\%filename%" "%Dest%\%NewName%"

当问题陈述只是“它不工作”时,很难诊断问题。请你的问题更完整地描述一下你预期会发生什么,以及这与实际结果有什么不同。请参阅,以获取关于什么是好的解释的提示。您好,我理解您,但问题是我没有结果,因此我确信我的代码是错误的。当我执行bat a命令时,windows打开,然后关闭,我看不到任何东西。简单的调试方法是暂时删除
@echo off
,然后进入
cmd.exe
并调用批处理文件
cmd.exe
在出现大多数错误时应保持打开状态,并可让您查看是否发生语法错误或错误的退出位置。我发现一些文件无法在文件夹2上写入日期。我从命令窗口运行脚本,并且可以看到消息“找不到文件”。我已经把全部问题写在下面了。非常感谢你。