Batch file 批处理脚本根据名称创建文件夹,添加到现有代码

Batch file 批处理脚本根据名称创建文件夹,添加到现有代码,batch-file,directory,Batch File,Directory,下面的代码工作正常,下面是它的函数列表: 它将基于前4个字符的文件移动到具有相同前4个字符的预创建文件夹中 如果文件夹不存在,它将不会移动文件,因为没有具有相同前4个字符的文件夹 @echo on setlocal enabledelayedexpansion cls pushd R:\Contracts\Sites for /f "tokens=*" %%1 in ('dir /a-d /b *') do ( set filename=%%1&set dirname=!fi

下面的代码工作正常,下面是它的函数列表:

  • 它将基于前4个字符的文件移动到具有相同前4个字符的预创建文件夹中
  • 如果文件夹不存在,它将不会移动文件,因为没有具有相同前4个字符的文件夹

    @echo on
    setlocal enabledelayedexpansion
    cls
    
    pushd R:\Contracts\Sites
    
    for /f "tokens=*" %%1 in ('dir /a-d /b *') do (
        set filename=%%1&set dirname=!filename:~0,4!
    
        for /f "tokens=*" %%A in ('dir /ad /b') do (
             set dirid=%%A & set dirid=!dirid:~0,4!
    
             if "!dirid!" equ "!dirname!" move %%1 %%A
        )        
    )
    
  • 我想在此代码中添加一个额外的函数。请看下面的例子

    我有5个文件

    • X32A-test.docx或X32A-test.pptx(只有一个docx或pptx,“决不能有两个同名”)
    • X32A-test.pdf
    • X32A-test.avi
    • X32A-test-eng.sub
    • X32A-test-small.jpg
    我希望代码创建一个文件夹,如果它不存在,根据文件名,如果它有扩展名docx或pptx

    因此,在上面的示例中,它将创建一个名为“X32A测试”的文件夹。然后,名称前面带有“X32A”的所有其他文件将移动到新创建的文件夹“X32A测试”

    我希望这足够清楚。如果没有,请向我询问更多信息


    谢谢

    您可以在
    中使用负偏移量!变量:~偏移量,伦评估如下:

    set fspec=X32A-test.docx
    echo !fspec:~-10!
    echo !fspec:~0,-10!
    
    上面的第二行给出了
    -test.docx
    ,您可以使用
    if
    语句(或两个)简单地对照您想要的两种可能性来检查它

    然后,您可以使用第三行获取名称的其余部分以创建目录

    以下示例脚本显示了如何执行此操作:

    @setlocal enableextensions enabledelayedexpansion
    @echo off
    set fspec=X32A-test.docx
    set bit1=!fspec:~-10!
    set bit2=!fspec:~0,-10!
    if .!bit1!.==.-test.docx. echo mkdir !bit2!
    if .!bit1!.==.-test.pptx. echo mkdir !bit2!
    endlocal
    
    我正在回显
    mkdir
    命令,而不是执行它,因此您需要取出
    echo
    。您还需要将
    set
    if
    语句集成到您的循环中,但是,根据目前的情况,您应该不会遇到什么问题


    如您在注释中所示,如果前四个字符是键,后五个字符决定是否创建目录,如:

    x32s-test.docx
    a21w-production.pptx
    xxxx-whatever_the_blazes_you_want.some_other_rubbish.docx
    
    那么你真的只对前四个和后五个感兴趣:

    @setlocal enableextensions enabledelayedexpansion
    @echo off
    set fspec=a12b-whatever_the_blazes_you_want.some_other_rubbish.docx
    set bit1=!fspec:~-5!
    set bit2=!fspec:~0,4!
    if .!bit1!.==..docx. echo mkdir !bit2!
    if .!bit1!.==..pptx. echo mkdir !bit2!
    endlocal
    
    这将检查正确的扩展和输出:

    mkdir a12b
    

    如预期。

    您可以在
    中使用负偏移量!变量:~偏移量,伦评估如下:

    set fspec=X32A-test.docx
    echo !fspec:~-10!
    echo !fspec:~0,-10!
    
    上面的第二行给出了
    -test.docx
    ,您可以使用
    if
    语句(或两个)简单地对照您想要的两种可能性来检查它

    然后,您可以使用第三行获取名称的其余部分以创建目录

    以下示例脚本显示了如何执行此操作:

    @setlocal enableextensions enabledelayedexpansion
    @echo off
    set fspec=X32A-test.docx
    set bit1=!fspec:~-10!
    set bit2=!fspec:~0,-10!
    if .!bit1!.==.-test.docx. echo mkdir !bit2!
    if .!bit1!.==.-test.pptx. echo mkdir !bit2!
    endlocal
    
    我正在回显
    mkdir
    命令,而不是执行它,因此您需要取出
    echo
    。您还需要将
    set
    if
    语句集成到您的循环中,但是,根据目前的情况,您应该不会遇到什么问题


    如您在注释中所示,如果前四个字符是键,后五个字符决定是否创建目录,如:

    x32s-test.docx
    a21w-production.pptx
    xxxx-whatever_the_blazes_you_want.some_other_rubbish.docx
    
    那么你真的只对前四个和后五个感兴趣:

    @setlocal enableextensions enabledelayedexpansion
    @echo off
    set fspec=a12b-whatever_the_blazes_you_want.some_other_rubbish.docx
    set bit1=!fspec:~-5!
    set bit2=!fspec:~0,4!
    if .!bit1!.==..docx. echo mkdir !bit2!
    if .!bit1!.==..pptx. echo mkdir !bit2!
    endlocal
    
    这将检查正确的扩展和输出:

    mkdir a12b
    

    正如所料。

    在您的案例中,使用简单的FOR而不是FOR/F更简单、更有效

    使用通配符比在每个文件中循环并单独移动它们更容易、更有效

    第一个循环查找.pptx和.docx文件,并根据需要创建文件夹

    第二个循环查找所有目录,并将以目录名开头的所有文件移动到该目录中

    @echo on
    setlocal enableDelayedExpansion
    cls
    
    pushd R:\Contracts\Sites
    
    for %%F in (*.docx *.pptx) do (
      set "folder=%%F"
      2>nul md !folder:~0,4!
    )
    for /d %%F in (*) do move %%F* %%F
    popd
    
    如果需要,您可以保护自己不受长度小于4的目录名的影响

    @echo on
    setlocal enableDelayedExpansion
    cls
    
    pushd R:\Contracts\Sites
    
    for %%F in (*.docx *.pptx) do (
      set "folder=%%F"
      set folder=!folder:~0,4!
      if !folder:~0,3! neq !folder! 2>nul md !folder!
    )
    for /d %%F in (????) do (
      set "folder=%%F"
      if "!folder:~0,3!" neq "%%F" move %%F* %%F
    )
    popd
    

    请注意,如果文件名包含
    ,此解决方案可能会失败。如果出现这种情况,那么您需要在循环中打开和关闭延迟扩展。

    在您的情况下,使用简单的FOR而不是FOR/F更简单、更有效

    使用通配符比在每个文件中循环并单独移动它们更容易、更有效

    第一个循环查找.pptx和.docx文件,并根据需要创建文件夹

    第二个循环查找所有目录,并将以目录名开头的所有文件移动到该目录中

    @echo on
    setlocal enableDelayedExpansion
    cls
    
    pushd R:\Contracts\Sites
    
    for %%F in (*.docx *.pptx) do (
      set "folder=%%F"
      2>nul md !folder:~0,4!
    )
    for /d %%F in (*) do move %%F* %%F
    popd
    
    如果需要,您可以保护自己不受长度小于4的目录名的影响

    @echo on
    setlocal enableDelayedExpansion
    cls
    
    pushd R:\Contracts\Sites
    
    for %%F in (*.docx *.pptx) do (
      set "folder=%%F"
      set folder=!folder:~0,4!
      if !folder:~0,3! neq !folder! 2>nul md !folder!
    )
    for /d %%F in (????) do (
      set "folder=%%F"
      if "!folder:~0,3!" neq "%%F" move %%F* %%F
    )
    popd
    

    请注意,如果文件名包含
    ,此解决方案可能会失败。如果出现这种情况,则需要在循环中打开和关闭延迟扩展。

    我可以看到整个过程(包括已实现的部分)如下所示:

  • 所有尚未在其“主”目录中的文件都将移动到那里

  • 对于所有剩余的
    .docx
    .pptx
    文件,根据文件名创建目录

  • 显然,第二步创造了新的“家园”,而这些“家园”到目前为止仍将“无人居住”。所以现在要做的就是重复第1步

  • 因此,我可能会重新组织您的流程,并根据附加要求,以以下方式实施:

    …
    
    PUSHD your_root_directory
    
    FOR /D %%D IN (*) DO (
      CALL :movefiles "%%D"
    )
    
    FOR %%F in (*.docx *.pptx) DO (
      MKDIR "%%~dpnF"
      CALL :movefiles "%%~dpnF"
    )
    
    …
    
    GOTO :EOF
    
    :movefiles
    SET "dirname=%~n1"
    SET "mask=%dirname:~0,4%*"
    MOVE "%~dp1%mask%" %1
    
    …
    推送您的根目录
    对于(*)中的/D%%D,请执行以下操作(
    调用:移动文件“%%D”
    )
    对于(*.docx*.pptx)中的%%F(
    MKDIR“%%~dpnF”
    调用:movefiles“%%~dpnF”
    )
    …
    后藤:EOF
    :移动文件
    设置“dirname=%~n1”
    设置“掩码=%dirname:~0,4%*”
    移动“%~dp1%掩码%%1”
    

    注意:步骤#2和#3可以作为单独的循环实现,也可以组合成一个循环。上面的脚本使用后一种方法。

    我可以看到整个过程(包括已经实现的部分)如下所示:

  • 所有尚未在其“主”目录中的文件都将移动到那里

  • 对于所有剩余的
    .docx
    .pptx
    文件,根据文件名创建目录

  • 显然,第二步创造了新的“家园”,而这些“家园”仍将“无人居住”