批处理脚本文件名截取时变量无法正确求值的问题求助
批处理文件名解析问题修复
问题根源
你的代码中,字符串截取语句使用了%prefixLength%、%packageNameLength%这类百分号引用变量,但在开启enabledelayedexpansion的for循环块内,百分号引用的变量会在整个循环块执行前被一次性静态解析,无法获取循环过程中动态更新的变量值,导致截取位置错误,最终输出空的packageName。
另外原strlen函数缺少返回结果的逻辑,无法将计算的长度传递回主代码,这也是潜在问题。
修复方案
方案1:修正原代码的变量引用与函数逻辑
将字符串截取语句改为通过call命令强制重新解析变量,同时补充strlen函数的结果返回逻辑:
@echo off setlocal enabledelayedexpansion for %%p in ( .\dir1\*.EXT ) do ( rem 带相对路径和扩展名的完整文件名 set "relationFileName=%%p" rem 仅文件名(不含路径) for %%f in ("!relationFileName!") do set filename=%%~nxf rem 移除扩展名 set "stripped_file=!filename:~0,-4!" rem 获取文件名长度,调用下方strlen函数 call :strlen filename_length stripped_file set "delimiter=-" set "lastIndex=-1" rem 从前往后遍历字符串,记录最后一个连字符的位置 for /l %%i in (0, 1, !filename_length!) do ( set char=!stripped_file:~%%i,1! if "!char!"=="!delimiter!" set lastIndex=%%i ) set /a nextIndex=lastIndex + 1 rem 移除前缀`value1-value2-`,长度设为14 set "prefixLength=14" set /a packageNameLength = lastIndex - prefixLength rem 按最后一个连字符拆分文件名(修改变量引用方式) call set packageName=!stripped_file:~%%prefixLength%%,%%packageNameLength%%! call set packageVersion=!stripped_file:~%%nextIndex%%! echo ^| !packageName! ^| !packageVersion! ^| ) endlocal REM ********* 函数 ***************************** :strlen <resultVar> <stringVar> ( setlocal EnableDelayedExpansion (set^ tmp=!%~2!) if defined tmp ( set "len=1" for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do ( if "!tmp:~%%P,1!" NEQ "" ( set /a "len+=%%P" set "tmp=!tmp:~%%P!" ) ) ) ELSE ( set len=0 ) endlocal & set "%~1=%len%" )
方案2:简化解析逻辑(更高效)
利用for /f的字符串拆分特性,直接跳过前两个带连字符的部分,再拆分剩余内容的文本和版本号,无需手动计算长度和遍历字符:
@echo off setlocal enabledelayedexpansion for %%p in (.\dir1\*.EXT) do ( rem 获取不带路径和扩展名的文件名 set "raw_name=%%~np" rem 跳过前两个带连字符的部分,得到剩余内容(如value3-2.45.13) for /f "tokens=3* delims=-" %%a in ("!raw_name!") do set "remaining=%%a-%%b" rem 拆分剩余内容为文本值和版本号 for /f "delims=-" %%x in ("!remaining!") do ( set "packageName=%%x" set "packageVersion=!remaining:*%%x-=!" ) echo ^| !packageName! ^| !packageVersion! ^| ) endlocal
这个方案避免了复杂的字符串长度计算和字符遍历,代码更简洁且不易出错。
内容的提问来源于stack exchange,提问作者Avraham Cohen
相关产品推荐
相关产品推荐

