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

时间:2012-01-21 10:03:08

标签: batch-file directory

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

  1. 它将基于前4个字符的文件移动到具有相同前4个字符的预先创建的文件夹
  2. 如果文件夹不存在,则不会移动文件,因为没有相同的拳头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
        )        
    )
    
  3. 我想在此代码中添加一个额外的功能。请看下面的例子。

    我有5个文件

    • X32A-test.docx或X32A-test.pptx(只有一个docx或pptx,“从不两个同名”)
    • X32A-检验.pdf
    • X32A-test.avi
    • X32A试验eng.sub
    • X32A试验small.jpg

    我希望代码在不存在的情况下创建文件夹,如果文件名具有扩展名docx或pptx,则根据文件名。

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

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

    谢谢

3 个答案:

答案 0 :(得分:2)

在您的情况下使用简单的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

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

答案 1 :(得分:1)

您可以在!var:~offset,len!评估中使用负偏移,如下所示:

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。您还需要将setif语句集成到您的循环中,但根据您目前的情况,您应该没有遇到任何问题。


如果你似乎在评论中指出,前四个字符是关键字,后五个字符决定是否制作目录,如:

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

正如所料。

答案 2 :(得分:1)

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

  1. 所有尚未进入" home"的文件目录移到那里。

  2. 对于剩下的所有.docx.pptx个文件,根据文件创建目录'名。

  3. 显然,第2步创建了新的"家庭"那些仍然是无人居住的"到目前为止。所以现在要做的就是重复步骤#1。

  4. 所以我可能会重新组织你的流程,并且根据附加要求,它可以通过这种方式实现:

    …
    
    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
    

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