在最后一次出现时拆分文件名'按'

时间:2015-03-03 03:29:02

标签: regex batch-file

我正在使用批处理脚本将文件从一个包含1000多个文件的主目录移动到子文件夹,根据文件名,必须创建子文件夹并相应地移动子文件夹。下面是场景/文件名格式。

  • title_or_work_done_by_user_name.xls

从这个文件名模式,我必须选择" user_name"并为该user_name创建一个文件夹。我发现了类似的代码,但是无法在最后一次'中完全破解它。

@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

有人可以帮我解决用户名'通过_'

将其分成最后一次出现的'

提前致谢:)

2 个答案:

答案 0 :(得分: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"
)

答案 1 :(得分: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_替换为文件名中不会发生(或限制使用)的字符串。我选择或者修改了一些(比如使用%~n 删除名称中的扩展名:可以使用。

reult是[string。] * required_name.xls

通过使用作为分隔符重复删除第一个标记,当没有第4个标记时,第二个标记将是必需的字符串。