根据文件名将文件移动到文件夹中

时间:2017-01-15 00:09:47

标签: windows batch-file cmd

我的表格中有一些文件:

filename1 1.ext
filename1 2.ext
filename1 3.ext
...
filename2 1.ext
filename2 100.ext
...
filename20 1.ext
filename20 15.ext
(etc.)

...其中filename可以包含空格。

我想分别将它们移到文件夹filename1filename2等。

我知道我可以执行for循环for %%i in (*.ext) do并使用set folder=%%~ni删除该扩展程序。所以我缺少的是如何在数字之前的空格之后删除所有内容,例如只获取filename1

我也知道我可以拆分变量folder,但是在这种情况下我不知道我需要分割哪个字符,虽然我知道它将是一个后跟数字的空格。

所以基本上,我想要这样的东西:

@echo off
set folder=

for %%i in (*.ext) do set folder=%%~ni & set folder=getfoldernamefromvariablefoldersomehow & mv %%i %folder%

3 个答案:

答案 0 :(得分:2)

@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"

FOR /f "delims=" %%a IN (
 'dir /b /a-d "%sourcedir%\*.ext" '
 ) DO (
 CALL :sub1 "%%a" %%a
)

GOTO :EOF

:sub1
SET "filename=%~1"
:subloop
SHIFT
SET "numname=%~1"
IF NOT "%~2"=="" GOTO subloop
CALL SET "dirname=%%filename: %numname%=%%
ECHO( MD "%sourcedir%\%dirname%" 2>nul
ECHO( MOVE "%sourcedir%\%filename%" "%sourcedir%\%dirname%\%numname%"
GOTO :eof

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

所需的MD命令仅用于ECHO用于测试目的。 在您确认命令正确之后,将ECHO(MD更改为MD以实际创建目录。

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

以基本形式执行所需文件的目录列表,不包含目录名。使用引号发送完整的fulename,而不使用子例程sub1

在子程序中,将源文件名保存在filename中,然后移动所提供的每个参数,直到没有第二个参数; numname中的值必须是最后一个或必需的文件名。

使用numname中的前导空格删除filename以获取所需的子目录名,生成该子目录并移动文件。

[根据评论编辑]

@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"

FOR /f "delims=" %%a IN (
 'dir /b /a-d "%sourcedir%\*.ext" '
 ) DO (
 CALL :sub1 "%%a" %%a
)

GOTO :EOF

:sub1
SET "filename=%~1"
SET "destdirname=%~2"
:subloop
SHIFT
SET "numname=%~1"
IF NOT "%~2"=="" GOTO subloop
CALL SET "dirname=%%filename: %numname%=%%
ECHO( MD "%sourcedir%\%destdirname%" 2>nul
ECHO( MOVE "%sourcedir%\%filename%" "%sourcedir%\%destdirname%\%numname%"
GOTO :eof

当你没有举例时,很难扼杀你的意图。

destdirname设置为输入sub1时的第二个参数,该参数将是第一个空格之前的第一组字符。

md不需要封闭,因为2>nul会抑制directory exists错误消息。

答案 1 :(得分:1)

这是一个可以满足您需求的脚本。它将最后一个 SPACE 分开,后跟文件名中的数字,并使用剩余的字符串作为移动目标目录的名称。

此方法可以正确处理文件名的所有有效字符,甚至是^&%!() 。它甚至可以正确处理包含 SPACE 加上数字加.ext的文件名。

所以这是代码:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_SOURCE=."
set "_TARGET=."

for /F "eol=| delims=" %%F in ('
    dir /B "%_SOURCE%\*.ext" ^| findstr /R /I /C:" [0123456789][0123456789]*\.ext$"
') do (
    set "FILE=%%F"
    call :SPLIT LAST REST "%%F"
    setlocal EnableDelayedExpansion
    2> nul mkdir "!_TARGET!\!REST!"
    ECHO move /Y "!_SOURCE!\!FILE!" "!_TARGET!\!REST!"
    endlocal
)

endlocal
exit /B


:SPLIT  rtn_last  rtn_rest  val_string
    setlocal DisableDelayedExpansion
    set "RES=" & set "STR=%~3"
    :LOOP
    for /F "tokens=1,* delims= " %%I in ("%STR%") do (
        if "%%J"=="" (
            set "RES=%%I"
        ) else (
            set "STR=%%J"
            goto :LOOP
        )
    )
    set "STR=%~3|"
    call set "STR=%%STR: %RES%|=%%"
    (
        endlocal
        set "%~1=%RES%"
        set "%~2=%STR:^^=^%"
    )
    exit /B

测试完脚本后,删除大写ECHO命令以实际移动任何文件。除非从/Y命令中删除move选项,否则文件会在没有提示的情况下被覆盖。要取消摘要消息(例如1 file(s) moved.),请将> nul添加到move命令行。请注意,如果您删除了/Y选项,则也会隐藏任何提示。

答案 2 :(得分:0)

感谢大家的意见。最后,我得到了一个解决方案:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

set "_source=C:\Users\kurok_000\Downloads"
set "_target=C:\Users\kurok_000\YandexDisk\Mangas"

for /f "eol=| delims=" %%f in ('dir /b "%_source%\*.7z"') do (  
    call :fixNames "%%f" %_source%
)

for /f "eol=| delims=" %%f in ('dir /b "%_source%\*.7z" ^| findstr /r /i /c:" [0123456789][0123456789]*\.7z$"') do (
    set "file=%%f"
    call :split last rest "%%f"
    setlocal EnableDelayedExpansion
    2> nul mkdir "!_target!\!rest!"
    move /y "!_source!\!file!" "!_target!\!rest!" >nul
    echo moved %%f to !_target!\!rest!
    endlocal
)
endlocal
exit /b

:split  rtn_last  rtn_rest  val_string
setlocal DisableDelayedExpansion
set "res=" & set "str=%~3"
:loop
for /f "tokens=1,* delims= " %%i in ("%str%") do (
    if "%%j"=="" (
        set "res=%%i"
    ) else (
        set "str=%%j"
        goto :loop
    )
)
:quit
set "str=%~3|"
call set "str=%%str: %res%|=%%"
(
    endlocal
    set "%~1=%res%"
    set "%~2=%str:^^=^%"
)
exit /b

:fixNames _file _folder
@echo off
setlocal EnableExtensions EnableDelayedExpansion

set "FILE=%1"
set "FILE=%file:~1,-1%"
set "folder=%2"

for /F "tokens=1,* delims=0123456789" %%A in ("%FILE%") do (
    set filename=!FILE:%%B=!%%~xB
    )
if not "%filename%"=="%FILE%" (rename "!folder!\!FILE!" "!filename!")