2015-03-03 25 views
0

我正在处理一个批处理脚本,用于根据文件名将文件从具有1000个以上文件的主目录移动到子文件夹,必须创建和移动子文件夹因此。以下是场景/文件名称格式。在'最后发生时'拆分文件名''

  • title_or_work_done_by_user_name.xls

从这个文件名模式,我要挑 “USER_NAME”,并创建该USER_NAME的文件夹。我发现了类似的代码,但无法在最后的'by'中完全打破它。

@ECHO OFF 
SETLOCAL 
SET "sourcedir=E:\Source" 
SET "destdir=E:\Destination" 


FOR /f "tokens=2*delims='by_'" %%a IN ('dir /b /a-d "%sourcedir%\*by_*.xls" ') DO (
ECHO %%a 
ECHO(MD "%destdir%\%%a" 2>nul 
ECHO(MOVE "%sourcedir%\*by_%%a.xls" "%destdir%\%%a\") 
pause 
GOTO :EOF 

有人可以通过在'by_'的最后一次出现时分割'user_name'来帮助我解压缩'user_name'。

感谢提前:)

回答

0

的DELIMS选项指定的字符,而不是字符串列表。因此,您的FOR循环将分割标记'_by。另外,您无法知道最后一个令牌的数字是多少。你的设计是一个死路一条。


选项1

这是一个纯粹的批量解决方案,将你想要做什么。我使用替换将文件名转换为伪路径。然后轻松选取所需的名称。延迟扩展用于访问设置它的同一个循环(代码块)内的变量值。唯一棘手的部分是根据需要打开和关闭延迟扩展,以保留任何!。如果包含!字符的FOR变量在扩展时启用延迟扩展,则它将被损坏。

@echo off 
setlocal disableDelayedExpansion 

for %%F in (*_by_*.jpg) do (

    %= Initialize name without extension =% 
    set "name=%%~nF" 

    %= Convert "Part1_by_Part2_by_Name" into "Part1\Part2\Name" =% 
    setlocal enableDelayedExpansion 
    for %%f in ("!name: - =\!") do (

    %= Only execute endlocal on the first iteration =% 
    if "!!" equ "" endlocal 

    %= The name might contain a dot, so need name and extension =% 
    set "name=%%~nxf" 
) 
    set "file=%%F" 
    setlocal enableDelayedExpansion 

    %= Hide error message if folder already exists =% 
    md "!name!" 2>nul 

    move "!file!" "!name!" 
    endlocal 
) 


选项2

的逻辑是简单的,如果使用的子程序,因为它避免了延迟扩展的问题。 CALL使代码效率较低(较慢),但这不应该成为这样的任务的问题。

@echo off 
setlocal disableDelayedExpansion 

for %%F in (*_by_*.jpg) do call :moveFile "%%F" 
exit /b 

:moveFile 
set "name=%~n1" 
for %%F in ("%name:_by_=\%") do set "name=%%~nxF" 
md "%name%" 2>nul 
move %1 "%name%" 
exit /b 


选项3

最简单的解决方案是使用我的JREPL.BAT utility - 混合的JScript /批执行正则表达式置换脚本。 JREPL是纯粹的脚本,可以在任何Windows XP机器上运行。

@echo off 
for /f "tokens=1,2 delims=: eol=:" %%A in (
    'dir /b /a-d *_by_*.jpg ^| jrepl "^.*_by_(.*)\.jpg" "$&:$1" /i' 
) do (
    md "%%B" 2>nul 
    move "%%A" "%%B" 
) 
0
@ECHO OFF 
SETLOCAL 

FOR %%a IN (

title_or_work_done_by_user_name.xls 
title_or_work_done_by_digby_hill.xls 
title_or_work_done_by_hook_or_by_crook.xls 

) DO CALL :process %%a 
GOTO :eof 

:process 
SET "name=%~1" 

:: This is the actual processing 
ECHO processing "%name%" 
SET "name=%name:_by_=.%" 
:loop 
FOR /f "tokens=1,2,3*delims=." %%p IN ("%name%") DO IF "%%s"=="" (SET "user_name=%%q") ELSE (
SET "name=%%q.%%r.%%s"&GOTO loop 
) 
ECHO extracted name is "%user_name%" 

GOTO :EOF 

我选择要使用的字符串_by_作为分隔符,因为有一些结束“的”名称。

只需将字符串_by_替换为文件名中不会出现(或限制使用)的字符串即可。我选择了 byt可能带有sme修饰(例如使用%~n可以使用从名称中删除扩展名。

的reult是[字符串] * required_name.xls

通过反复去除使用所述第一令牌。作为分隔符,当没有4th +标记时,则第二个标记将是必需的字符串。