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 命令仅 ECHO
ed 用于测试目的。 确认命令正确后,将ECHO(MD
更改为MD
以实际创建目录。附加 2>nul
以抑制错误消息(例如,当目录已经存在时)
所需的 MOVE 命令仅 ECHO
ed 用于测试目的。 确认命令正确后,将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
)
我想根据如下所示的文件名创建文件夹:
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 命令仅 ECHO
ed 用于测试目的。 确认命令正确后,将ECHO(MD
更改为MD
以实际创建目录。附加 2>nul
以抑制错误消息(例如,当目录已经存在时)
所需的 MOVE 命令仅 ECHO
ed 用于测试目的。 确认命令正确后,将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
)