【问题标题】:Batch Script to create folder based on name, add to existing code批处理脚本根据名称创建文件夹,添加到现有代码
【发布时间】:2012-01-21 10:03:08
【问题描述】:

下面的代码运行良好,下面是它的功能列表:

  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
        )        
    )
    

我想在这段代码中添加一个额外的功能。请看下面的例子。

我有 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-test”的文件夹。然后名称前面带有“X32A”的所有其他文件将被移动到新创建的文件夹“X32A-test”中。

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

谢谢

【问题讨论】:

  • @Christian.K - 谢谢。我无法让它全部变成代码。
  • 不用担心。只需将您想要的所有文本标记为代码并使用编辑器中的“{}”按钮(或将每个代码行缩进 4 个或更多空格)。

标签: batch-file directory


【解决方案1】:

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

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

【讨论】:

  • 它会创建一个文件夹,但它应该使用整个名称。例如。 2382-test-music-luck.docx,它应该做一个文件夹 2382-test-music-luck.dock 谢谢
  • @Arthor:对不起,但是'所以在上面的例子中,它会创建一个名为:“X32A-test”的文件夹。'——是你的 话,伙计。现在你说它应该包括扩展。您在问题中是否还有其他没有正确提及的内容?
  • 对不起...一秒钟.....只有这个...2382-test-music-luck 它不需要扩展名..只有整个文件夹名称..对不起@Andriy M
  • @dbenham:很可能使用~n 说明符就足够了。
  • @Andriy M - 你好 Andriy,你能告诉我我需要把代码放在哪里吗?我一直在玩它,但没有得到我想要的结果。谢谢
【解决方案2】:

我可以像这样看到整个过程(包括已经实现的部分):

  1. 尚未在其“主”目录中的所有文件都移到那里。

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

  3. 显然,第 2 步创建了新的“家”,到目前为止,这些“家”仍然“无人居住”。所以现在剩下要做的就是重复第 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

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

【讨论】:

    【解决方案3】:

    您可以在!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。您还需要将 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
    

    正如预期的那样。

    【讨论】:

    • 您好,感谢您的快速回复。我理解这个概念,但我认为有一个问题。 X32A-test.docx 不是唯一的文件名。按照上面的相同示例,将有 100 个文件。例如X32A-test.docx、XS1A-test.docx、64SA-test.docx。我认为它必须首先识别 docx 或 pptx,然后获取不带扩展名的文件名,然后检查文件夹名称是否存在,如果没有创建它,如果存在,继续。谢谢
    • @Arthor,这就是它的作用。两个if 语句将检测文件名的结尾(在这种情况下使用bit1,最后十个字符)并且仅在它们匹配特定模式时才起作用。如果采取行动,mkdir 将使用除最后十个字符之外的所有字符 bit2 来创建目录。目录是否存在并不重要。如果没有,mkdir 将创建它。如果是这样,它只会出错并继续。
    • 太棒了....好吧,让我试一试...请注意我不是编码员,但我愿意学习...所以来...谢谢跨度>
    • Aaaa OK 我注意到了我的错误,想象一下这些文件名:X32A-test.docx、X31B-the-living-garden.docx、1S2A-the-cream-of-all.docx。对不起,我不是故意听起来很愚蠢。前 4 个字符是主键,后面是文件名。这是否会使文件即使认为文件名不是测试。我只是确保...
    • 没问题,@Arthor,我已经更新了答案,以便它只检查扩展名并且只使用前四个字符作为目录名称。如果这不是您想要的,那么适应它应该相对容易。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-23
    • 2019-04-20
    • 1970-01-01
    • 1970-01-01
    • 2011-04-05
    • 1970-01-01
    相关资源
    最近更新 更多