Windows 根据文件名批量创建文件夹

Windows Batch create folders based on file names

我想根据如下所示的文件名创建文件夹:

file with words 01.wav
file with words 02.wav
file with words 03.wav
file with more words 01.wav
file with more words 02.wav
...

树应该是这样的

Folder
|----file with words
     |----file with words 01.wav
     |----file with words 02.wav
     |----file with words 03.wav
|----file with more words
     |----file with more words 01.wav
     |----file with more words 02.wav

并且里面的文件应该保持原来的名字 如何解决每个数字前的最后一个空格? 我无法为 "tokens" 指定固定值,因为最后一个空格的位置因文件而异。 这是我的方法:

FOR /f "tokens=1*" %%a IN (
 'dir /b /a-d "* *.wav"'
 ) DO (
 ECHO MD %%a
 ECHO MOVE "%%a %%b" .\%%a\
)
PAUSE

-> ECHO调试结果

@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o"
PUSHD "%sourcedir%"
FOR /f "delims=" %%a IN (
  'dir /b /a-d *.wav '
  ) DO (
 SET "filename=%%a"
 SET "dirname=%%a"
 CALL :genmove
)
popd

GOTO :EOF

:genmove
IF "%dirname:~-1%" neq " " set "dirname=%dirname:~0,-1%"&goto genmove
set "dirname=%dirname:~0,-1%"
ECHO(MD "%dirname%"
ECHO(MOVE "%filename%" ".\%dirname%\"
GOTO :eof

您需要更改 sourcedir 的设置以适合您的情况。

所需的 MD 命令仅 ECHOed 用于测试目的。 确认命令正确后,将ECHO(MD 更改为MD 以实际创建目录。附加 2>nul 以抑制错误消息(例如,当目录已经存在时)

所需的 MOVE 命令仅 ECHOed 用于测试目的。 确认命令正确后,将ECHO(MOVE更改为MOVE以实际移动文件。附加 >nul 以禁止报告消息(例如 1 file moved

简单地为文件和目录生成相同的名称,trim 关闭名称的最后一个字符,直到该字符是 space,trim 关闭,你有需要目录名和文件名。

@echo off
    setlocal enableextensions disabledelayedexpansion

    for %%a in (*.wav) do (
        set "filename=%%~na"
        setlocal enabledelayedexpansion
        for %%b in ("::\!filename: =\!\..") do ( endlocal & set "filename=%%~pnxb" )
        setlocal enabledelayedexpansion
        for /f "tokens=*" %%b in ("!filename:\= !") do ( 
            endlocal 
            if not exist "%%b\" md "%%b"
            if exist "%%b*.wav" move /y "%%b *.wav" "%%b"
        )
    )

代码背后的想法是遍历文件列表,对于每个文件,名称中的空格都替换为反斜杠 (file\with\words),因此我们可以使用 for可替换参数查询最后一个元素的 "parent folder"(没有结尾数字的名称),然后用空格替换反斜杠以获得最终文件夹名称。

包含多个 setlocal/endlocal 以处理可能包含感叹号(启用延迟扩展时出现问题的字符)的文件名。

该代码尝试仅使用一个 move 命令移动每个集合中的所有匹配文件,但根据真实姓名,其他集合中的文件也可能匹配。为了避免它,行

if exist "%%b*.wav" move /y "%%b *.wav" "%%b"

应该转换成

 move /y "%%a" "%%b\"

所以文件一个一个地移动没有问题。

这是一个使用 JREPL.BAT 的版本 - 一个执行正则表达式文本替换的混合 JScript/batch 实用程序。

此解决方案的优点是它只尝试移动名称与 {baseName}{space}{digit}{digit} 匹配的 .wav 文件,如果无法创建则不会移动文件{baseName} 文件夹,因为文件 {baseName} 已经存在。这些功能可以添加到已经发布的纯批处理解决方案中。但是,我发现通过 JREPL.BAT.

构建强大的解决方案更容易
@echo off
for /f "tokens=1,2 delims=:" %%A in (
  'dir /b "* ??.wmv" ^| jrepl "(.+?) +\d\d\.wmv$" "+':'+[=10=]" /i /jmatch'
) do (
  if not exist "%%A\" if not exist "%%A" (
    md "%%A"
  ) else echo Can't create folder "%%A" because a file exists with that name
  if exist "%%A\" move "%%B" "%%A" >nul
)