如何在第n个地方进行反向搜索并查找特定字符,然后删除字符

时间:2017-12-08 15:01:38

标签: batch-file

实际:

ABCDEFGHIJ_CPW_ABC_KT_#ABCD_ABCDEFGH_ABCDEFGHIJKL L01_10_18_2017_02_53_22_015_10_244_36_7.xml

需要:

ABCDEFGHIJ_CPW_ABC_KT_#ABCD_ABCDEFGH_ABCDEFGHIJKL L01.xml

想要从第11个" _"删除.xml的所有内容。反过来。

这是一个示例文件名格式。我喜欢目录中的10-15K文件。我需要重命名/更改所有文件。基本上需要从" _"(在L01之后)删除到"。"。

2 个答案:

答案 0 :(得分:0)

很好的挑战......

你必须涉及一些数学(如果你使用支持REGEX的语言,可能会更简单)

@echo off
setlocal enabledelayedexpansion
set count=11
set "string=ABCDEFGHIJ_CPW_ABC_KT_#ABCD_ABCDEFGH_ABCDEFGHIJKL L01_10_18_2017_02_53_22_015_10_244_36_7.xml"
echo %string%
call :remove "%string%" 11
echo %return%
goto :eof

:remove [String] [Integer]
set "name=%~n1"
set n=0
for /l %%i in (150,-1,0) do (
  if "!name:~%%i,1!" equ "_" set /a n+=1, p[!n!]=%%i
)
set /a x=%2-1
set pos=!p[%x%]!
set return=!name:~0,%pos%!%~x1

被调用的子程序计算_并记住每个位置。因此,我们可以“轻松”计算应该切割字符串的位置。

不是一个漂亮或明显的代码,但是 - 好吧,我们是批处理......

您可能需要将150调整为大于最长字符串的数字(文件名,如您的示例所示)。

修改:处理文件夹中的所有文件名,只需添加另一个for

@echo off
setlocal enabledelayedexpansion
set count=11
for %%f in (*.xml) do (
  echo %%f
  call :remove "%%f" 11
  echo !return!
)
goto :eof

:remove [String] [Integer]
set "name=%~n1"
set n=0
for /l %%i in (150,-1,0) do (
  if "!name:~%%i,1!" equ "_" set /a n+=1, p[!n!]=%%i
)
set /a x=%2-1
set pos=!p[%x%]!
set return=!name:~0,%pos%!%~x1

答案 1 :(得分:0)

在此方法中,每个下划线分隔的标记都以tail字符串连接,但是当连接的标记的数量达到给定的数字(在此示例中为11)时,第一个标记也会从字符串中删除;最终结果是tail字符串中有11个最后一个标记。之后,这些最后的标记将从原始输入字符串中删除。

@echo off
setlocal EnableDelayedExpansion

set "input=ABCDEFGHIJ_CPW_ABC_KT_#ABCD_ABCDEFGH_ABCDEFGHIJKL L01_10_18_2017_02_53_22_015_10_244_36_7.xml"

echo Input ="%input%"
set n=11
set "tail="
for %%a in ("%input:_=" "%") do (
   if !n! gtr 0 (
      set "tail=!tail!%%~a_"
   ) else (
      set "tail=!tail:*_=!%%~a_"
   )
   set /A n-=1
)
set "output=!input:_%tail:~0,-1%=!.xml"
echo Output="%output%"

以较短的形式:

@echo off
setlocal EnableDelayedExpansion

set "input=ABCDEFGHIJ_CPW_ABC_KT_#ABCD_ABCDEFGH_ABCDEFGHIJKL L01_10_18_2017_02_53_22_015_10_244_36_7.xml"

echo Input ="%input%"
set n=11
set "tail="
set "aux=%input%_"
set "token=%aux:_=" & (if !n! gtr 0 (set "tail=!tail!!token!_") else set "tail=!tail:*_=!!token!_") & set /A n-=1 & set "token=%"
set "output=!input:_%tail:~0,-1%=!.xml"
echo Output="%output%"

在这个更简单的方法中,计算分离下划线的数量并用于消除原始字符串之后的部分。但是,此方法仅在要保留的标记数小于32时才有效:

@echo off
setlocal EnableDelayedExpansion

set "input=ABCDEFGHIJ_CPW_ABC_KT_#ABCD_ABCDEFGH_ABCDEFGHIJKL L01_10_18_2017_02_53_22_015_10_244_36_7.xml"

echo Input ="%input%"
set n=-11
for %%a in ("%input:_=" "%") do set /A n+=1
for /F "tokens=%n%* delims=_" %%a in ("%input%") do set "output=!input:_%%b=!.xml"
echo Output="%output%"