如何根据文件名的第一和第二部分创建文件夹并将文件移动到文件夹中?

时间:2017-03-30 05:28:21

标签: batch-file

我创建了以下批处理脚本,以根据今天的日期创建文件夹,然后根据文件名将文件分组到文件夹中。

例如文件

JIM_BRICKMAN_QPS.avi
JIM_BRICKMAN_Slice.avi
JIM_BRICKMAN_Slice.jpg

移至文件夹BRICKMAN

这样可以正常工作,但是,尝试修改批处理文件以将新创建​​的文件夹移动到新创建的日期文件夹失败,或者在完成循环时覆盖文件夹。

for /F "tokens=1-4 delims=/" %%A in ('date /t') do (
    set DateDay=%%A
    set DateMonth=%%B
    set DateYear=%%C
)
set CurrentDate=%DateDay%-%DateMonth%-%DateYear%
if not exist "%CurrentDate%" md %CurrentDate%

for %%A in (*.avi *.jpg) do (
    for /f "tokens=1,* delims=_" %%D in ("%%~nA") do (
        md "%%D" 2>nul
        echo Moving file %%A to folder %%D
        move "%%A" "%%D" >nul
    )
)

echo Finished

此外,我似乎无法让令牌忽略第一个分隔符,因此该文件夹标题为JIM_BRICKMAN而不只是BRICKMAN

修改

我在评论中的建议后重写了批处理文件:

set "CurrentDate=%DATE:~-10,2%-%DATE:~-7,2%-%DATE:~-4%"
if not exist "%CurrentDate%" md %CurrentDate%
for %%A in (*.avi *.jpg) do (
    for /f "tokens=1,2 delims=_" %%D_%%E in ("%%~nA") do (
        md "%%D_%%E" 2>nul
        move "%%A" "%%D_%%E" >nul
    )
)

但剧本似乎爆炸了。我试图捕获错误,但尽管我在脚本中放置 PAUSE ,它仍然关闭。

1 个答案:

答案 0 :(得分:0)

在开发中双击批处理文件并不是一个好主意,因为这会导致开始

%SystemRoot%\System32\cmd.exe /c "batch file name with full path and extension"

由于可以在命令提示符窗口中运行cmd /?时读取,因此选项/C意味着在执行命令后立即关闭命令进程及其控制台窗口,可执行文件或脚本独立于结束执行的原因完成。

为了在开发中调试批处理文件,

更好
  1. 打开命令提示符窗口,
  2. 使用 CD 命令将当前目录更改为批处理文件目录和
  3. 运行批处理文件,方法是键入其名称并按 RETURN ENTER
  4. 对于应该独立于哪个目录是当前目录的批处理文件,建议省略第2点并运行批处理文件,并输入用双引号括起来的完整路径,文件名和文件扩展名,当前目录不是批处理文件的目录。

    批处理文件在命令提示符窗口中执行:

    %SystemRoot%\System32\cmd.exe /K BatchFileNameAsTyped
    

    选项/K表示保持命令进程正在运行,这导致在执行命令/可执行文件/脚本后也保持命令提示符窗口打开,从而可以读取错误消息。

    向上箭头向下箭头可用于在命令提示符窗口中输入后重新加载命令行,这样可以在创建后再次运行批处理文件在GUI文本编辑器中修改。

    @echo off从第一行批处理文件中删除,或更改为@echo ON,或使用命令 REM ::注释掉此行(无效标签)在开始时,还可以看到Windows命令解释器在应用立即环境变量扩展后真正执行的行以及在语法错误的情况下发生错误。

    错误的第二批代码是行:

    for /f "tokens=1,2 delims=_" %%D_%%E in ("%%~nA") do (
    

    指定为循环变量必须始终为1个字符。正确的是:

    for /f "tokens=1,2 delims=_" %%D in ("%%~nA") do (
    

    我的计算机上的命令echo %DATE%输出我的帐户和我的区域设置今天01.04.2017

    命令echo %DATE:~-10,2%-%DATE:~-7,2%-%DATE:~-4%输出01-04-2017

    所以脚本的这部分可以工作。

    提示:格式YYYY-MM-DD的目录列表优于格式DD-MM-YYYY。默认情况下按字母顺序排序的格式为YYYY-MM-DD的目录列表将自动使用此日期格式,也从最旧到最新排序。日期格式DD-MM-YYYY导致在默认情况下按字母顺序排序的目录的奇怪列表。

    此任务的批处理文件可以是:

    @echo off
    set "CurrentDate=%DATE:~-10,2%-%DATE:~-7,2%-%DATE:~-4%"
    for %%A in (*.avi *.jpg) do (
        for /F "tokens=1,2 delims=_" %%D in ("%%~nA") do (
            if not "%%E" == "" (
                md "%CurrentDate%\%%D_%%E" 2>nul
                move /Y "%%A" "%CurrentDate%\%%D_%%E\"
            ) else (
                md "%CurrentDate%\%%D" 2>nul
                move /Y "%%A" "%CurrentDate%\%%D\"
            )
        )
    )
    set "CurrentDate="
    

    内循环如何工作对这项任务最有意义。

    for /F"%%~nA"表示命令 FOR 应该只处理* .avi或* .jpg文件的文件名,而不包含外部找到的文件扩展名FOR 循环。

    delims=_表示 FOR 命令应使用下划线作为分隔符将字符串拆分为多个部分(标记)。第一个文件名是JIM_BRICKMAN_QPS,它将被拆分为:

      分配给 FOR 命令行中指定的循环变量JIM
    1. D
    2. BRICKMAN分配给循环变量E,这是D之后的ASCII table中的下一个字符和
    3. QPS分配给循环变量F
    4. 此字符串拆分功能是循环变量被解释为区分大小写的原因,而环境变量的解释不区分大小写。

      指定tokens=1,2只关注第一个和第二个字符串部分。因此内部 FOR 可以在已经确定前两个下划线分隔的字符串并将它们分配给循环变量DE之后停止字符串拆分。

      FOR 执行命令块,如果它可以确定至少1个由下划线分隔的字符串。因此循环变量D可能具有字符串值,但循环变量E是空字符串,例如,如果文件名不包含任何下划线。这就是 IF 条件的原因。

      命令 MD 创建时启用了命令扩展,默认情况下为整个目录树。因此,在搜索* .avi和* .jpg文件之前,不必显式创建日期子目录。这很好,因为它避免了当前目录中没有* .avi和* .jpg文件时创建空日期目录。

      由于当前目录中的* .avi和* .jpg文件应移至DD-MM-YYYY\Token1_Token2,因此当然还需要在创建目录和移动文件时使用今日日期字符串指定环境变量。 / p>

      MD 输出的错误消息,如果该目录存在(或由于缺少权限而无法创建目录)以处理 STDERR ,将重定向{{1设备 NUL 来抑制它。

      MOVE 命令与选项2>nul一起使用,即使当前文件已存在于目标文件夹中,也会将文件移动到目标文件夹。

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

      • /Y
      • echo /?
      • for /?
      • if /?
      • md /?
      • move /?

      另请阅读Microsoft有关Using Command Redirection Operators

      的文章
相关问题