Batch file 按精确扩展名获取文件的通配符

Batch file 按精确扩展名获取文件的通配符,batch-file,command-line,Batch File,Command Line,在诊断需要使用*.log扩展名循环文件的较大批处理脚本时,我发现了一个有趣的行为。在包含以下文件的示例目录中: bar.log foo.log foo.log.ignore foo.log.log-1676521099 无关 。。。我的小测试脚本: @echo off setlocal enabledelayedexpansion set DEF_LOG="C:\test\*.log" for %%i in (%DEF_LOG%) do ( echo %%i ) 。。。打印此文件:

在诊断需要使用
*.log
扩展名循环文件的较大批处理脚本时,我发现了一个有趣的行为。在包含以下文件的示例目录中:

bar.log
foo.log
foo.log.ignore
foo.log.log-1676521099
无关
。。。我的小测试脚本:

@echo off
setlocal enabledelayedexpansion
set DEF_LOG="C:\test\*.log"
for %%i in (%DEF_LOG%) do (
    echo %%i
)
。。。打印此文件:

C:\test\bar.log
C:\test\foo.log
C:\test\foo.log.log-1676521099
深入挖掘,我发现Windows通配符就是这样设计的:

C:\>dir“C:\test\*.log”/b
原木
foo.log
foo.log.log-1676521099

我的问题是:如何列出所有以
.log
结尾的文件?

使用内部检查循环仅获取具有所需扩展名的文件

@echo off
setlocal enabledelayedexpansion

rem set desired extension for additional filter
set extn=.log
set DEF_LOG="C:\temp\*.log"

for %%i in (%DEF_LOG%) do (
    rem if file extension is equal to our ext
    if "%%~xi"=="%extn%" echo %%i
)

最简单、最快捷的方法是用扩展名测试修饰符%%~x

@echo off&cls
for /f "delims=" %%a in ('dir /b') do if /i "%%~xa"==".log" echo %%a
pause

该行为的来源是短文件名。除非禁用,否则将为超过旧8.3格式的文件名分配一个与8.3格式匹配的短名称。如果扩展名超过3个字符,则短名称将由长名称扩展名的前3个字符组成。执行
dir/x“C:\test\*.log”
查看短名称

在查找匹配项时,所有命令都将测试长名称和短名称

获得所需结果的常用方法是使用管道连接到FINDSTR的DIR/B。请注意,在扩展FOR变量时应避免使用延迟扩展,因为这将损坏包含
的值
字符可能出现在文件名中

@echo off
pushd "C:\test"
for /f "eol=: delims=" %%F in ('dir *.log^|findstr /lie ".log"') do echo %%~fF
popd

但是,有趣的是,名为test.log.txt的文件没有通过C:\test*.log过滤器…感谢您提供了有关
启用延迟扩展
的额外提示-我刚刚验证了它是否会损坏包含感叹号的文件名。(因为我的另一个功能需要它,所以我怀疑我的脚本需要完全重写。)很好,sacha,我喜欢它(--°)