我正在尝试将T:
驱动器上的所有文件(和目录)组织到两个目录中:Pre2010
和PostAnd2010
。应根据文件的上次修改时间对文件进行组织 - 因此,如果文件T:\dirA\fileA1
具有时间戳12/28/2015 03:42pm
,则应将其移至T:\PostAnd2010\dirA\
,并保留相同的文件名。此外,如果文件T:\dirA\fileA2
具有时间戳1/13/2009 12:23am
,则应将其移至T:\Pre2010\dirA\
,并使用相同的文件名。因此,新的Pre2010
和PostAnd2010
目录应保持与先前T:
驱动器相同的目录结构,但按日期拆分文件。
我没有任何编写批处理文件的经验,但我一直在努力!到目前为止,这是我的代码:
@ECHO OFF
setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
chdir /d T:
FOR /r %%i IN (*) do (
FOR %%a in (%%i) do set FileDate=%%~ta
set year=!FileDate:~6,4!
if !year! LSS 2010 (
REM Move to T:\Pre2010\<filepath>
echo !year! is before 2010
) else (
REM Move to T:\PostAnd2010\<filepath>
echo !year! is 2010 or after
)
REM echo !year!
pause
)
echo Done.
pause
这似乎工作正常,但后来我注意到,有时会将这一年打印为~6,4
而不是实际年份。我检查了导致问题的文件的时间戳,但对他们来说似乎并不奇怪。我不确定为什么FileDate
和year
在某些文件中是空白的。我想在完成移动文件部分之前弄清楚这个问题。
任何帮助将不胜感激!谢谢!
答案 0 :(得分:1)
robocopy /?
寻求帮助,尤其是:
/MAXAGE:n :: MAXimum file AGE - exclude files older than n days/date.
/MINAGE:n :: MINimum file AGE - exclude files newer than n days/date.
/MAXLAD:n :: MAXimum Last Access Date - exclude files unused since n.
/MINLAD:n :: MINimum Last Access Date - exclude files used since n.
(If n < 1900 then n = n days, else n = YYYYMMDD date).
使用/L
查看robocopy会做什么。
使用/MIR
进行实际移动。
rem /L to see what it does
robocopy l:\test\fileage\all l:\test\fileage\old /MINAGE:20151002 /L /MIR
或
rem /MIR to actually move the files
robocopy l:\test\fileage\all l:\test\fileage\old /MINAGE:20151002 /MIR
rem /L to see what it does
robocopy l:\test\fileage\all l:\test\fileage\new /MAXAGE:20151002 /L /MIR
或
rem /MIR to actually move the files
robocopy l:\test\fileage\all l:\test\fileage\new /MAXAGE:20151002 /MIR
我做的是copy c:\windows\system32\nv*.dll l:\test\fileage\all
这给了我一个小文件列表,这些文件在20151002日期之前/之后有可见的日期中断。
您应该能够轻松适应您的目录名称。
答案 1 :(得分:1)
Kory Gill's answer使用robocopy
引导您完成最简单,最有效的任务:
rem Remove the `/L` switch to actually move items:
robocopy "T:\" "T:\Pre2010" "*.*" /L /E /MOVE /XD "Pre2010" "PostAnd2010" /MINAGE:20100101
robocopy "T:\" "T:\PostAnd2010" "*.*" /L /E /MOVE /XD "Pre2010" "PostAnd2010" /MAXAGE:20100101
但是,我想依靠你的代码。
您使用for /R
循环遍历T:
根目录中的所有项目。目标目录Pre2010
和PostAnd2010
也位于此处。由于您正在移动文件,因此您正在操作由for /R
枚举的目录树。根据{{3}},for /R
在迭代之前不枚举整个目录树,因此可能会出现意外结果。要解决此问题,请使用dir /B /S
命令并通过for /F
循环解析其输出,以便在循环实际开始迭代所有循环之前枚举整个目录树项目。请参阅以下代码:
@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "YEAR=2010"
set "OLDDIR=Pre2010"
set "NEWDIR=PostAnd2010"
chdir /D "T:\"
for /F "eol=| delims=" %%F in ('
dir /S /B /A:-D "*.*"
') do (
set "FILEDATE=%%~tF"
rem The following depends on the region settings:
if "FILEDATE:~6,4!" LSS %YEAR% (
xcopy /L "%%~fF" "%%~dF\%OLDDIR%%%~pF"
) else (
xcopy /L "%%~fF" "%%~dF\%NEWDIR%%%~pF"
)
)
call :CLEANUP
endlocal
exit /B
:CLEANUP
ECHO del /Q "*.*"
for /F "eol=| delims=" %%D in ('
dir /S /B /A:D "*.*"
') do (
set "PATHNAME=%%~fD"
if "!PATHNAME:%OLDDIR%=!"=="!PATHNAME!" (
if "!PATHNAME:%NEWDIR%=!"=="!PATHNAME!" (
ECHO rmdir /S /Q "%%~fD"
)
)
)
exit /B
除了for /R
和for /F
替换dir /B /S
之外,这就是我所做的:
OLDDIR
,NEWDIR
和YEAR
,分别为YEAR
并立即查询FILEDATE:~6,4
; move
替换为xcopy
,因为move
仅移动文件,因此最后只剩下空目录;所以我使用xcopy
并稍后删除源文件和目录; 从两个/L
命令中移除xcopy
开关以实际复制任何内容,否则它只会列出要复制的内容; echo
和pause
语句
for /F
循环之后,跳转到:CLEANUP
子程序; :CLEANUP
例程,当然除了两个目标目录之外,它会删除源T:\
中的所有内容。首先,删除根目录中的文件,然后删除源目录树; 删除大写ECHO
(两次)以实际删除任何源文件和目录,否则只输出要删除的内容; 答案 2 :(得分:0)
我很感谢收到的两个答案的帮助!他们都帮助我找到了最终解决方案。为了简单起见,我决定使用robocopy而不是我最初使用的循环。我在驱动器上运行了脚本,它有大约50GB的数据,花了几个小时。我有点担心robocopy的输出,因为它报告跳过的文件和目录;它可能没问题。这是我最终使用的内容:
@echo off
chdir /d T:
robocopy T: "T:\Pre2010" /MINAGE:20091231 /S
pause
robocopy T: "T:\PostAnd2010" /MAXAGE:20100101 /S
pause
echo Done!
pause