我正在尝试提取当前目录中所有文件名(pdf文件)的一部分。
文件名的长度因最后一部分(日期时间和扩展名)而异,但总是16个字符。剩下的部分总是有不同的长度。即使我要求的部分也可能有不同的长度。
我尝试使用获得here的lastIndexOf函数。
filename例如:academyo-nonpo- 2582365 -082416051750.pdf
我想以Bold的形式提取部分。 我尝试修剪最后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
作为第3个参数传递给函数的变量的引用似乎没有返回所需的值。 我不知道这里有什么问题。
答案 0 :(得分: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
答案 1 :(得分:0)
查看this answer。我们首先要计算令牌的数量(你仍然需要在此之前修剪字符串),然后获取最后一个令牌。
在显示"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
的内容也似乎正常工作,但是在正确完成后,它会出现一次错误消息,语法错误我无法找到...
如果您可以忽略该错误(其他一切正常),这可能会有所帮助。
答案 2 :(得分: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
此方法基本上用标准-
标记化字符 SPACE 替换每个cmd
,并使用标准for
循环遍历生成的字符串(no {{ 1}}选项)。当前迭代的部分存储在变量/F
中,其内容首先被复制到PART
以获得一次循环迭代的延迟。所以倒数第二部分最终存储在PREV
。
请注意,如果字符串/文件因delayed expansion而包含感叹号,则此脚本可能会返回意外结果。