如何根据作为文件名一部分的年份值将文件移动到文件夹

时间:2015-08-04 15:30:43

标签: parsing batch-file move

我们有近250万个档案数据文件需要根据创建它们的年份进行组织。我们需要将文件从我们NAS上的当前文件夹移动到另一个文件夹,该文件夹是创建文件的年份。目标文件夹是四个字符的年份值(2003年,2004年等)。文件名的格式为AAAAAAAAA_YYYYMMDD_BBBBBB.dfa,其中YYYY是创建文件的年份值。文件扩展名可以是.dfa或.dfc。适当年份的文件夹已存在,但错误放置在错误年份的文件必须移动到相应的年份文件夹。

我需要一个批处理文件,将文件从当前位置移动到NAS上相应的年份文件夹,但不知道如何从文件名中解析年份值以将文件移动到正确的年份。

有人可以帮我处理批处理文件或脚本吗?

1 个答案:

答案 0 :(得分:0)

以下批处理文件以递归方式遍历变量ROOT给出的根目录,并将文件移动到相应的年份文件夹中:

@echo off

rem specify the root directory here (the directory containing the year folders):
set ROOT="."
rem define the file search pattern(s) here:
set PATTERNS="*.dfa" "*.dfc"
rem set this to non-empty for flexible file name parsing:
set FLEXMODE=
rem set this to a log file path
rem (log contains date/time, TRUE/FALSE for move success/failure, source, dest.):
set LOGF=".\movement.log"

setlocal EnableDelayedExpansion

rem loop through every file recursively
for /R %ROOT% %%F in (%PATTERNS%) do (
  rem extract parent folder name
  set PARENT=%%~dpF
  set PARENT=!PARENT:~-5,4!
  rem parse file name, extract year portion
  if defined FLEXMODE (
    for /F "tokens=2 delims=_" %%N in ("%%~nF") do (
      set YEAR=%%N
      set YEAR=!YEAR:~,4!
    )
  ) else (
    set YEAR=%%~nF
    set YEAR=!YEAR:~10,4!
  )
  rem check whether parent folder name equals year portion of file name
  if not "!PARENT!"=="!YEAR!" (
    rem move file if not in appropriate year folder (no overwrite)
    if not exist "%%~dpF..\!YEAR!\%%~nxF" (
      move /Y "%%~fF" "%%~dpF..\!YEAR!" > nul
      echo %DATE%, %TIME%    TRUE    "%%~fF"    "%%~dpF..\!YEAR!\%%~nxF"
    ) else (
      echo %DATE%, %TIME%    FALSE   "%%~fF"    "%%~dpF..\!YEAR!\%%~nxF"
    )
  ) >> %LOGF%
)

endlocal

预要件:

  • 相应地设置起始块中的变量:
    • ROOT:完整的根目录路径;
    • PATTERNS:用于搜索的文件模式;
    • FLEXMODE:如果文件名AAAAAAAAA中的AAAAAAAAA_YYYYMMDD_BBBBBB.*部分的长度不同,则将其设置为非空值;在这种情况下,第一个下划线_用于查找年YYYY;否则(空值),年份由其位置提取;
    • LOGF:包含四列(以4个空格分隔)的日志文件的路径和名称:日期和时间,TRUE / FALSE表示成功/失败,来源文件路径,目标文件路径;已正确放置的文件未在此处记录;
  • 年份文件夹作为给定根目录的直接子项放置;
  • 所有文件都位于年份文件夹内(错误或正确的年份);
  • 您在整个根目录树中拥有足够的访问权限;
  • 进行脚本测试,将rem放在move命令前面并查看日志文件;

说明:

  • 核心元素是遍历目录层次结构的for /R循环;
  • 对于每个文件,变量PARENT设置为直接父目录名称(~dp中的%%~dpF修饰符提取驱动器和路径,包括尾部反斜杠);
  • 取决于FLEXMODE,从文件名中提取年YYYY部分(如果定义了FLEXMODE,则使用for /F循环来解析文件名和将其拆分为下划线分隔的标记,第二个标记的前4个字符是年份,存储在YEAR;如果FLEXMODE为空,则提取偏移10的4个字符并存储在{{1 }});
  • 接下来,根据父目录名YEAR检查提取的YEAR;如果相等,则不做任何其他事情并转到下一个PARENT次迭代;否则,文件将被移动,但仅在目的地尚不存在时才会移动;
  • 最后,for /R生成并返回一个日志字符串,然后将其重定向到指定的日志文件;
  • 用于修改变量值(echoPARENT)并在循环结构(或其他代码块)中使用它们,delayed expansion是必需的;