0

我正在尝试提取当前目录中所有文件名(pdf 文件)的一部分。

文件名的长度会有所不同,但最后一部分(日期时间和扩展名)始终为 16 个字符。其余部分将始终具有不同的长度。即使是我需要的部分也可能有不同的长度。

我尝试使用这里获得的 lastIndexOf 函数。

文件名 例如:academyo-nonpo- 2582365 -082416051750.pdf

我想提取粗体部分。我首先尝试修剪最后 17 个字符(这部分将始终具有固定长度。)然后尝试获取“-”的最后一个索引(因为第一个部分可以具有可变字符长度。)并修剪字符直到该位置,它应该返回文件名的所需部分。

@echo off
Setlocal enabledelayedexpansion

For %%# in ("%~dp0\*.pdf") Do (
    Set "File=%%~nx#"
    Set "File=!File:~0,-17!"
    Set "lio2="
    @echo on
    echo !File!
    @echo off
    call :lastindexof !File! - lio2
    Set "File=!File:~%lio%!"

)

Pause&Exit

:lastindexof [%1 - string ; %2 - find last index of ; %3 - if defined will store the result in variable with same name]
@echo off
setlocal enableDelayedExpansion 


set "str=%~1"
set "p=!str:%~2=&echo.!"
set "splitter=%~2"

set LF=^


rem ** Two empty lines are required
echo off
for %%L in ("!LF!") DO (
    for /f "delims=" %%R in ("!splitter!") do ( 
        set "var=!str:%%R=%%L!"
    )
)

for /f  delims^=^" %%P in ("!var!") DO ( 
    set "last_part=%%~P"  
)

if "!last_part!" equ ""  if "%~3" NEQ "" (
 echo "not contained" >2 
 endlocal
 set %~3=-1 
 exit
) else (
 echo "not contained" >2 
 endlocal

set argv=original
set $strLen=for /L %%n in (1 1 2) do if %%n==2 (%\n%
      for /F "tokens=1,2 delims=, " %%1 in ("!argv!") do (%\n%
         set "str=A!%%~2!"%\n%
    echo -1 
)
setlocal DisableDelayedExpansion

set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"
        set "len=0"%\n%
           for /l %%A in (12,-1,0) do (%\n%
             set /a "len|=1<<%%A"%\n%
             for %%B in (!len!) do if "!str:~%%B,1!"=="" set /a "len&=~1<<%%A"%\n%
           )%\n%
           for %%v in (!len!) do endlocal^&if "%%~b" neq "" (set "%%~1=%%v") else echo %%v%\n%
      ) %\n%
) ELSE setlocal enableDelayedExpansion ^& set argv=,


%$strlen% strlen,str
%$strlen% plen,last_part
%$strlen% slen,splitter

set /a lio=strlen-plen-slen
endlocal & if "%~3" NEQ "" (set %~3=%lio%) else echo %lio%
exit /b

作为第三个参数传递给函数的变量的引用似乎没有返回所需的值。我不知道这里有什么问题。

4

3 回答 3

0

要以粗体显示该部分,请执行以下操作:

例子#

@Echo Off
SetLocal EnableDelayedExpansion
For %%# in ("%~dp0*.pdf") Do (
    Set "File=%%~n#"
    Set "File=!File:~-20,7!"
    Echo=!File!%%~x#)
Pause

好的呢?

@Echo Off
SetLocal EnableDelayedExpansion
For %%# in ("%~dp0*.pdf") Do (
    Set "File=%%~n#"
    Set "File=!File:~,-13!"
    Call :Sub "!File:-=\!%%~x#")
Pause
:Sub
Echo=%~nx1
于 2016-09-27T08:17:59.753 回答
0

看看这个答案。想法是首先计算令牌的数量(您仍然必须在此之前修剪字符串)然后获取最后一个令牌。

在它说的第一个循环中"tokens=1*",您必须将其编辑为以下内容:并"tokens=1* delims=-"在第二个循环中添加. 您的脚本应该看起来像这样:delims=-%i%

@echo off
SetLocal EnableDelayedExpansion

For %%# in ("%~dp0\*.pdf") Do (
Set "File=%%~nx#"
Set "File=!File:~0,-17!"
Set "lio2="
@echo on
echo !File!
@echo off
call:subfunction !File! - lio2
Set "File=!File:~%lio%!"
)

:subfunction
set var1=%1
set var2=%var1%
set i=0

:loopprocess
for /F "tokens=1* delims=-" %%A in ( "%var1%" ) do (
  set /A i+=1
  set var1=%%B
  goto loopprocess )

for /F "tokens=%i% delims=-" %%G in ( "%var2%" ) do set last=%%G

echo %last%
    REM do what you want with last here!

我对其进行了测试,即使使用类似的东西它似乎也能正常工作ac-ade-myo-n-on-po-15482729242321654-082416051750.pdf,但是在正确完成后,它会给出一条错误消息,并出现我找不到的语法错误......

如果您可以忽略该错误(其他一切正常),这可能会有所帮助。

于 2016-09-27T08:47:24.717 回答
0

要提取最后一个连字符和倒数第二个连字符之间的部分,您可以使用以下脚本(提供字符串/文件作为命令行参数):

@echo off
setlocal EnableExtensions EnableDelayedExpansion

set "SEP=-"

for %%A in (%*) do (
    set "ITEM=%%~A"
    set "PREV="
    if defined ITEM (
        for %%B in ("!ITEM:%SEP%=" "!") do (
            set "PREV=!PART!"
            set "PART=%%~B"
        )
        if defined PREV (
            echo(!PREV!
        )
    )
)

endlocal
exit /B

这种方法基本上将 every 替换-为标准cmd标记化字符SPACE,并使用标准循环遍历生成的字符串for(无/F选项)。当前迭代的部分存储在变量PART中,首先将其内容复制到PREV其中以获得一个循环迭代的延迟。所以倒数第二部分最终存储在PREV.

请注意,如果字符串/文件由于延迟扩展而包含感叹号,则此脚本可能会返回意外结果。

于 2016-09-27T09:48:00.610 回答