Batch file 批处理文件,以处理以特定字符结尾的文件名

Batch file 批处理文件,以处理以特定字符结尾的文件名,batch-file,cmd,Batch File,Cmd,我试图运行一个批处理文件,该批处理文件调用特定文件夹中的三个文件,每个文件以不同的字符集结尾。我可以将路径映射到文件夹没有问题,代码也可以工作,但是我不能在我要查找的三个特定结尾字符之前创建通配符。文件夹中的文件名长度是可变的,我不知道这些长度,因为它们是由以前的批处理文件创建的,但都以特定的三个字符(_BX.tif)结尾。我使用了下面的代码,但它不识别_B4.tif之前的*,因此它实际上在cmd行中打印* for /d %%a in ("%mypath%\*") do ( script.exe

我试图运行一个批处理文件,该批处理文件调用特定文件夹中的三个文件,每个文件以不同的字符集结尾。我可以将路径映射到文件夹没有问题,代码也可以工作,但是我不能在我要查找的三个特定结尾字符之前创建通配符。文件夹中的文件名长度是可变的,我不知道这些长度,因为它们是由以前的批处理文件创建的,但都以特定的三个字符(_BX.tif)结尾。我使用了下面的代码,但它不识别_B4.tif之前的*,因此它实际上在cmd行中打印*

for /d %%a in ("%mypath%\*") do (
script.exe "%%a\*_B4.tif" "%%a\*_B3.tif" "%%a\*_B2.tif" "%%a\*_output.tif"
)
有没有其他方法可以添加通配符,以便文件名可以更改,但它只搜索最后三个字符


非常感谢

我想我可以通过迭代一组文件(以_B4.tif结尾的文件),提取文件名的前导部分,然后检查相应的_B3.tif和_B2.tif是否存在来完成您想要的操作:

@echo off
setlocal
:main
set mypath=%1
for %%f in (%mypath%\*_B4.tif) do call :get_prefix_and_execute_script "%%f"
exit /b

REM subroutine to extract prefix of filename and call script.exe
:get_prefix_and_execute_script
set filename=%1
echo Filename: %filename%
REM extract the first portion of the filename, excluding the remaining
REM 8 characters for: _B4.tif" (also excluding trailing quotation mark).
REM Start at 1 rather than 0 to exclude the leading quotation mark.
set prefix=%filename:~1,-8%
echo Prefix: %prefix%
set B4="%prefix%_B4.tif"
set B3="%prefix%_B3.tif"
set B2="%prefix%_B2.tif"
if not exist %B3% echo %B3% not found! & exit /b
if not exist %B2% echo %B2% not found! & exit /b
REM all 3 files exist...so call script.exe
set output="%prefix%_output.tif"
script.exe %B4% %B3% %B2% %output%
echo.
exit /b
for/D命令用于遍历目录,而不是文件。所以这里我只使用了一个普通的for,没有开关

如果有问题的话,这个脚本应该处理包含空格的文件名

此脚本假设_B4.tif、_B3.tif和_B2.tif都存在。例如,如果您有:file_B3.tif和file_B2.tif,但file_B4.tif不存在,此脚本将对此保持沉默

我实际上没有script.exe,因此我将用以下内容替换该调用:

echo script.exe %B4% %B3% %B2% %output%
现在,如果我创建以下文件:

echo. > test_B4.tif
echo. > test_B3.tif
echo. > test_B2.tif
echo. > "test me_B4.tif"
echo. > "test me_B3.tif"
echo. > "test me_B2.tif"
注意:这些文件实际上不是*.tif文件,因为它们只包含换行符。这只是为了演示脚本如何处理文件名

这里还有一些不符合模式的:

echo. > abc.tif
echo. > other.txt
echo. > xyz_B4.tif
echo. > xyz_B3.tif
目录列表显示:

06/11/2017  01:06 PM    <DIR>          .
06/11/2017  01:06 PM    <DIR>          ..
06/11/2017  01:06 PM                 3 abc.tif
06/11/2017  12:55 PM               851 filesets.bat
06/11/2017  01:06 PM                 3 other.txt
06/11/2017  12:49 PM                 3 test me_B2.tif
06/11/2017  12:49 PM                 3 test me_B3.tif
06/11/2017  12:49 PM                 3 test me_B4.tif
06/11/2017  12:49 PM                 3 test_B2.tif
06/11/2017  12:49 PM                 3 test_B3.tif
06/11/2017  12:49 PM                 3 test_B4.tif
06/11/2017  01:06 PM                 3 xyz_B3.tif
06/11/2017  01:06 PM                 3 xyz_B4.tif
              11 File(s)            881 bytes

假设每个目录中只有一个文件
*\u B4.tif
,那么文件
*\u B3.tif
*\u B2.tif
*\u B4.tif
具有相同的名称,并且文件
*\u output.tif
也应该具有相同的名称部分
*
,您可以尝试一下,鉴于
*
零件本身不包含任何
.

rem//枚举目录:
对于“%mypath%\*”中的/D%%a,请执行以下操作(
rem//获取文件“*\u B4.tif`并提取“*`部分:
对于('dir/b“%~a\*\u B4.tif”中的/F“delims=\ueol=”%b,请执行以下操作(
rem//将`*`零件从文件`*\u B4.tif`复制到所有其他文件:
script.exe“%%~a\%%~b_B4.tif”“%%~a\%%~b_B3.tif”“%%~a\%%~b_B2.tif”“%%~a\%%~b_output.tif”
)
)

如果
*.\u B4.tif
的名称部分
*.
本身包含
.
,则方法会变得有点复杂:

rem//枚举目录:
对于“%mypath%\*”中的/D%%a,请执行以下操作(
rem//Get文件“*\u B4.tif”:
对于(“%%a\*\u B4.tif”)中的%%b,请执行以下操作(
rem//存储当前迭代的目录和文件名`*\u B4.tif`:
设置“FDIR=%%~a”
设置“NAME=%%~nxb”
rem/*通过拆分将文件名部分`*`提取到最后出现的``前面
rem在每个` `处输入名称,遍历各个部分,重新分配每个部分
rem是一个变量,延迟一次迭代,附加到先前的值上;
rem切换延迟扩展以不丢失文件名中的感叹号:*/
设置“COLL=“&set”项=”
setlocal EnableDelayedExpansion
对于(“!NAME:=”“!”)中的%%c,请执行以下操作(
对于(“!COLL!!ITEM!|”)中的/F“delims=eol=|”%%d,请执行以下操作(
端部
设置“COLL=%%d”
)
设置“项=%%~c”
setlocal EnableDelayedExpansion
)
rem//将`*`零件从文件`*\u B4.tif`复制到所有其他文件:
设置“NAME=!FDIR!\!COLL:~1,-1!”
script.exe“!NAME!_B4.tif”“!NAME!_B3.tif”“!NAME!_B2.tif”“!NAME!_output.tif”
端部
)
)

我尝试了这个方法,它会在每个出口/b关闭cmd窗口。它似乎也无法识别文件名。例如,找到的
回显:%filename\u prefix%
只返回“~1,-8”。也不确定这8个字符来自何处,_BX.tif之前的数字是可变的。无论如何感谢您的尝试。嗯,“exit”应该关闭cmd.exe,而“exit/b”要么从当前子例程返回,要么在顶层终止脚本。这来自批处理脚本中。“退出”将终止在命令行上执行的cmd.exe。格式:set variable=%other\u variable:~x,-y%表示:从%other\u variable%提取子字符串,从字符x开始,直到字符串结尾之前的y个字符为止(因为它是负数)。文件名的开头部分长度可变,但结尾部分的长度固定。好的,你能建议一种方法返回实际的文件名吗?我可以看看我是否能让代码正常工作。我可以看到您使用%filename\u prefix%的想法,但它实际上并没有返回文件名,只是
Found:~1,-8
@burt46不确定它是否有用,但我编辑了脚本以使用单独的变量:%filename%vs%prefix%以保持清晰。感谢Rich的评论。我这边的问题是,输出无法调用文件名。通过修改脚本,我看到了这一点<代码>前缀:~1,-8 script.exe“~1,-8_B4.tif”“~1,-8_B3.tif”“~1,-8_B2.tif”“~1,-8_output.tif”每个目录中是否只有一个文件与
*\u B4.tif
/
/
*\u B2.tif
匹配?是否有其他
*\u B?.tif
文件(例如
*\u B1.tif
)?每个目录中
\u B?.tif
前面的名称部分是否始终相同?我假设
*\u output.tif
还不存在;
*
代表什么?是的,文件夹中只有一个_B4.tif。总共有12个文件,_B1.tif到_B12.tif。_B?.tif之前的名称部分会更改,但所有_B1.tif的名称都相同
C:\test>filesets .
Filename: ".\test me_B4.tif"
Prefix: .\test me
script.exe ".\test me_B4.tif" ".\test me_B3.tif" ".\test me_B2.tif" ".\test me_output.tif"

Filename: ".\test_B4.tif"
Prefix: .\test
script.exe ".\test_B4.tif" ".\test_B3.tif" ".\test_B2.tif" ".\test_output.tif"

Filename: ".\xyz_B4.tif"
Prefix: .\xyz
".\xyz_B2.tif" not found!