这是我的第一个问题,所以如果我不像以前那样写信,我会事先道歉......
我有一个包含大量文件(图像,视频等)的深层文件夹结构,因此我想将这些文件复制到平面结构以获得更好的概览。 我想保留(至少)原始日期属性:创建日期和最后修改日期。
问题1 )我想在同一个文件夹中有不同文件夹中有同名00001.jpg的文件,所以我想在复制过程中为文件名添加创建日期/时间。
00001.jpg
变为2015-11-17_11-23-35_00001.jpg
到目前为止一切顺利。或者不好......
Copy
和XCopy
没有给我一个选项来做到这一点,而不至少丢失创建日期信息(我没有找到两者的解决方案)。
现在我尝试将文件(按文件逐个文件)与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提前为每个提示,也批评我的解决方案方法。也许我脑子里有马眼罩,没有看到简单的解决方案?!
答案 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
开头的行(请注意开头的空格)或00
到39
范围内的数字。< / 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