Windows批处理禁用延迟扩展时MediaInfo提取内容无法赋值给变量问题
问题根因与修复方案
这是Windows批处理最容易踩的括号代码块预解析坑,和MediaInfo命令、延迟扩展配置都没有本质关系。
cmd执行带括号的整块代码时,会在整个块正式启动运行前,一次性把块内所有普通%变量%、可识别的循环变量全部替换为当前的实际值;块运行过程中不管你怎么给变量赋值,都不会改变块内已经提前替换好的内容。
你当前代码的两个核心错误点,刚好完全踩中了这个机制的坑:
- 你写的
echo test: %%G、echo video: %tester%是放在外层for /R的大括号作用域里,根本没进到内层for /f的循环块里- 外层块预解析时,
%tester%还没被赋过值,直接被替换成空字符串,所以最终输出的video:后面啥内容都没有 %%G是内层for的专属循环变量,外层for的解析阶段根本识别不到这个变量,只会把它当普通文本转成%G的字面量打印,这就是你看到固定输出test: %G的原因
- 外层块预解析时,
- 你之前测试
set /p tester=<temp.txt也出现同样问题,逻辑完全一致:哪怕set命令成功把temp.txt的内容读到tester变量里,同个外层块里的echo video: %tester%早在块启动前就已经被替换成空值了,根本读不到新赋的内容。
适配你场景的修复实现
你因为文件名可能带感叹号不能开启延迟扩展,这个需求完全没问题,根本不需要动延迟配置,只要把嵌套的代码块拆解开,避开预解析的影响就行:
@echo off setlocal disabledelayedexpansion for /R %%B in (*.mp4,*.mkv) do ( mediainfo.exe "--Inform=Video;%%Format%%" "%%B" > temp.txt call :parse_media_content ) rem 循环结束后清理临时文件 del temp.txt 2>nul pause exit /b :parse_media_content rem 独立子程序的代码块,每次call时单独完成变量解析 set "tester=" for /f "usebackq delims=" %%G in (temp.txt) do ( set "tester=%%G" echo test: %%G echo video: %tester% ) goto :eof
改动说明
- 全程保持
disabledelayedexpansion状态,完全兼容文件名带感叹号的场景,不会出现文件名被截断、解析错误的问题 - 读取temp.txt的逻辑通过
call拆成独立子程序,子程序的变量展开是在每次调用时实时完成的,不会被外层for块的预解析提前替换成空值 - 给for /f加上
delims=参数,避免MediaInfo输出的格式内容如果带空格,被默认的空格分隔逻辑截断成单个字段,能完整读到整行输出内容。
内容的提问来源于stack exchange,提问作者dcol
相关产品推荐
相关产品推荐

