我的表格中有一些文件:
filename1 1.ext filename1 2.ext filename1 3.ext ... filename2 1.ext filename2 100.ext ... filename20 1.ext filename20 15.ext (etc.)
...其中filename
可以包含空格。
我想分别将它们移到文件夹filename1
,filename2
等。
我知道我可以执行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%
答案 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!")