批处理:保留(创建)日期复制文件到另一个(展平)文件夹结构,包括。重命名文件以避免重复

时间:2017-09-24 21:10:11

标签: batch-file copy robocopy file-attributes

这是我的第一个问题,所以如果我不像以前那样写信,我会事先道歉......

事实:

我有一个包含大量文件(图像,视频等)的深层文件夹结构,因此我想将这些文件复制到平面结构以获得更好的概览。 我想保留(至少)原始日期属性:创建日期和最后修改日期。

问题1 )我想在同一个文件夹中有不同文件夹中有同名00001.jpg的文件,所以我想在复制过程中为文件名添加创建日期/时间。

00001.jpg变为2015-11-17_11-23-35_00001.jpg

到目前为止一切顺利。或者不好......

CopyXCopy没有给我一个选项来做到这一点,而不至少丢失创建日期信息(我没有找到两者的解决方案)。

现在我尝试将文件(按文件逐个文件)与robocopy复制到新文件夹,并在复制的文件上使用ren来“预先设置”文件名前的日期/时间信息。

这是一个简单的test.bat示例:

setlocal enableextensions enabledelayedexpansion

robocopy . ./zzz original.txt /copy:DATSO
pause

rem :: formatted creation date of original file will be here, in real life
set "myDate=2015-11-17-_11-23-35"

rem rename "./zzz/original.txt" "!myDate!_renamed.txt" ::doesnt work: why? relative path??

rem :: this will do what I want - original creation date is kept on copy file
FOR %%A IN (zzz/original.txt) DO REN "%%~fA" "!myDate!_%%~nxA"

[可能] Problem2 )是否有更好的方法可以做到这一点,或者我可能遇到线程问题(异步执行)。可能是,我尝试在robocopy完成复制过程之前重命名文件(例如对于大文件)?

对不起,我是一个完全批量的新手(也是SO的海报;)。

ThanX提前为每个提示,也批评我的解决方案方法。也许我脑子里有马眼罩,没有看到简单的解决方案?!

  1. [编辑:发布格式]
  2. [编辑:发布内容 - >文件名前面的日期/时间,以便更好地排序]

2 个答案:

答案 0 :(得分:0)

可以使用命令 DIR 来递归列出指定文件夹及其子文件夹中的所有文件以及创建日期/时间。

日期/时间的格式取决于 Windows地区和语言设置。

在我的机器上使用英语Windows 7和区域F:\Temp\Test的示例输出在运行命令行dir F:\Temp\Test\* /A-D /S /TC时配置为德国:

 Volume in drive F is TEMP
 Volume Serial Number is 1911-26A4

 Directory of F:\Temp\Test

25.09.2017  17:26           465.950 SimpleFile.ccl
               1 File(s)        465.950 bytes

 Directory of F:\Temp\Test\Test Folder

25.09.2017  17:26           360.546 Test File.tmp
               1 File(s)        360.546 bytes

     Total Files Listed:
               2 File(s)        826.496 bytes
               0 Dir(s)  58.279.460.864 bytes free

此输出使用findstr /R /C:"^ Directory of" /C:"^[0123][0123456789]"进行过滤,只能获得以 Directory of开头的行(请注意开头的空格)或0039范围内的数字。< / p>

 Directory of F:\Temp\Test
25.09.2017  17:26           465.950 SimpleFile.ccl
 Directory of F:\Temp\Test\Test Folder
25.09.2017  17:26           360.546 Test File.tmp

此过滤后的输出由 FOR 循环处理,命令由 FOR 执行。

@echo off
for /F "tokens=1-2*" %%A in ('dir "F:\Temp\Test\*" /A-D /S /TC ^| %SystemRoot%\System32\findstr.exe /R /C:"^ Directory of" /C:"^[0123][0123456789]" 2^>nul') do (
    if "%%A %%B" == "Directory of" (
        set "FilePath=%%C"
    ) else (
        set "CreationDate=%%A"
        set "CreationTime=%%B"
        for /F "tokens=1*" %%I in ("%%C") do set "FileName=%%J"
        call :RenameFile
    )
)
goto :EOF

:RenameFile
set "NewName=%CreationDate:~-4%-%CreationDate:~3,2%-%CreationDate:~0,2%_%CreationTime:~0,2%-%CreationTime:~3,2%_%FileName%"
ren "%FilePath%\%FileName%" "%NewName%"
goto :EOF

建议将命令echo放在命令ren之前的最后一行,以便首先验证预期的新文件名。

ren "F:\Temp\Test\SimpleFile.ccl" "2017-09-25_17-26_SimpleFile.ccl"
ren "F:\Temp\Test\Test Folder\Test File.tmp" "2017-09-25_17-26_Test File.tmp"

注意:批处理文件必须位于此批处理文件未处理的文件夹中,否则批处理文件本身将在运行时重命名,这会破坏批处理文件的处理。

要了解使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完全阅读为每个命令显示的所有帮助页面。

  • call /?
  • dir /?
  • echo /?
  • for /?
  • goto /?
  • if /?
  • ren /?
  • set /?

顺便说一句: WinRAR 可以将文件添加到RAR存档中,除了上次修改时间之外还有创建和上次访问时间,并将文件解压缩到另一个目录,同时恢复创建和上次访问时间使用Windows内核的SetFileTime功能。

答案 1 :(得分:0)

目前我使用Locale独立日期。我使用令牌来计算日期/时间。

for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set datetime=%%I
rem :: format it to YYYY-MM-DD_hh-mm-ss
set myDateTime=%datetime:~0,4%-%datetime:~4,2%-%datetime:~6,2%_%datetime:~8,2%-%datetime:~10,2%-%datetime:~12,2%

这不是问题。

澄清: 列表也不是问题。 我循环抛出所有相关文件,没有问题(批处理文件和输出目录及其子树除外);

我的问题是:

我为每个文件调用robocopy ,然后重命名该文件以保存原始创建日期。我担心它会对大文件和调用次数(许多次数)产生问题(多线程?)

批处理执行是否真的序列化了?在我尝试重命名文件之前,进程是否等待robocopy,它已经完成。我可以为vry大文件遇到死锁吗?我会用一些假的千兆字节文件对它进行测试。

您的建议使用winrar 听起来很有趣。 如果我可以将所有文件添加到一个大型存档(带有结构),最后将其提取到目标目录...我会尝试它;)

如果它不起作用,我将用java编程! 我知道该怎么做,那就是我的游乐场:D

我认为编写一个简单的批处理文件很容易,为我做这个,但它似乎并不像我想象的那么容易

无论如何 ThanX