批处理:问号通配符不使用点

时间:2017-07-17 15:35:19

标签: batch-file

我有一个脚本试图按标题查找重复的视频。我从文件名中推断出标题,我试图在关键字之间使用?通配符搜索以相同名称开头的其他文件:

for /r %%i in ("%string%*") do set /a count+=1

其中%string的格式为The?Title?S01E01所以我使用"The?Title?S01E01*"进行搜索,当单词用空格等分隔时效果很好但是当分隔符为点时它会失败。我该如何克服这个问题?在我曾经做过的每个剧本中,我都必须为此添加一个单独的处理程序。

2 个答案:

答案 0 :(得分:3)

您对?的理解是错误的。它不匹配任何单个字符。相反,它匹配 .之外的任何字符。如果没有匹配的字符(在名称末尾或.之前),那么?将匹配“无”而不会失败。

我在SuperUser上的How does the Windows RENAME command interpret wildcards?处描述了这种行为。

此行为对于几乎所有Windows标准命令都是一致的。但至少有一个例外,where命令为pointed out by aschipfl。他的where解决方案可能是解决您问题的最简单方法。

一个更复杂的替代方法是使用FINDSTR和适当派生的正则表达式来优化结果。对于字符串中的所有*,初始FOR搜索将替换?

set "string2=%string:.=\.%"
set "string2=%string2:?=.%"
set "string2=%string2:*=.*%"
set "string2=%string2:^=\^%"
set "string2=%string2:$=\$%"
for /r %%i in ("%string:?=*%*") do echo %%~nxi|findstr /ric:"^%string2%" >nul && set /a count+=1

答案 1 :(得分:2)

似乎for(如dir或其他内部命令)也被句点.弄糊涂了,因为它表示基本名称的文件扩展名的分隔符。< / p>

外部命令where(我认为是自Windows Vista以来),对{@ 1}}和?这样的通配符处理略有不同,这看起来很合适为你的任务:

*

在上面的代码中,for /F "delims=" %%i in ('where /R "." "The?Title?S01E01*"') do set /A "count+=1" 正在生成当前目录及下面的匹配文件列表,然后由for /F loop捕获并解析,以使每个项目在变量{{1}中可用}}

要防止where在未找到文件的情况下显示错误消息,请执行以下操作:

%%i

请注意转义重定向where,这是不要尝试在for /F "delims=" %%i in ('where /R "." "The?Title?S01E01*" 2^> nul') do set /A "count+=1" 上执行的必要条件。

如果只想搜索当前目录中的匹配文件而不是整个树,请将命令行更改为此(注意前缀^>):

for /F