如何在batch file中循环匹配通配符的文件

我有一组基本文件名,每个名字'f'都有两个文件'f.in'和'f.out'。 我想写一个batch file(在Windows XP中)通过所有的文件名,为每一个它应该:

  • 显示基本名称'f'
  • 对“f.in”执行操作
  • 在'f.out'上执行另一个操作

除了search* .in(或* .out)之外,我没有办法列出这些基本文件名。

假设你有两个程序处理这两个文件,process_in.exe和process_out.exe:

for %%f in (*.in) do ( echo %%~nf process_in "%%~nf.in" process_out "%%~nf.out" ) 

%%〜nf是一个replace修饰符,仅将%f扩展为文件名。 在https://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/batch.mspx?mfr=true (在页面中间)查看其他修饰符,或者在下一个答案中查看。

您可以使用此行来打印您的桌面的内容:

 FOR %%I in (C:\windows\desktop\*.*) DO echo %%I 

一旦你有了%%Ivariables就很容易对它执行一个命令(只需用你的程序replaceecho这个词)

另外,FORvariables引用的replace已经增强现在可以使用下面的可选语法:

 %~I - expands %I removing any surrounding quotes (") %~fI - expands %I to a fully qualified path name %~dI - expands %I to a drive letter only %~pI - expands %I to a path only %~nI - expands %I to a file name only %~xI - expands %I to a file extension only %~sI - expanded path contains short names only %~aI - expands %I to file attributes of file %~tI - expands %I to date/time of file %~zI - expands %I to size of file %~$PATH:I - searches the directories listed in the PATH environment variable and expands %I to the fully qualified name of the first one found. If the environment variable name is not defined or the file is not found by the search, then this modifier expands to the empty string 

在上面的例子中, %I和PATH可以被其他有效的值replace。 %~语法由一个有效的FORvariables名称终止。 采用大写字母variables名称(例如%I使其更具可读性,并避免与大小写不敏感的修饰符混淆。

你可以通过inputFOR /?获得完整的文档FOR /?

就我所见,最简单的方法是使用for循环来调用第二个batch file进行处理,将第二个文件作为基本名称。

根据for /? help,basename可以使用nifty〜n选项来提取。 所以,基本脚本将会是:

 for %%f in (*.in) do call process.cmd %%~nf 

然后,在process.cmd中,假定%0包含基本名称并相应地执行。 例如:

 echo The file is %0 copy %0.in %0.out ren %0.out monkeys_are_cool.txt 

在一个脚本中可能有一个更好的方法来做到这一点,但是如何在一个batch file中的单个for循环中提取多个命令,我总是有点朦胧。

编辑:这太棒了! 我不知何故错过了文档中显示可以在FOR循环中执行多行块的页面。 我要去回去,现在重写一些batch file…

有一个通常用于MS服务器的工具(据我记忆)称为forfiles :

上面的链接包含帮助以及到Microsoft下载页面的链接。

扩大在Nathans岗位。 以下将在一个batch file中做很多工作。

 @echo off if %1.==Sub. goto %2 for %%f in (*.in) do call %0 Sub action %%~nf goto end :action echo The file is %3 copy %3.in %3.out ren %3.out monkeys_are_cool.txt :end 

以下代码过滤以给定子string开头的文件名。 通过对子string子string提取和IF语句进行处理,可以将其更改为适合不同的需求:

 echo off rem filter all files not starting with the prefix 'dat' setlocal enabledelayedexpansion FOR /R your-folder-fullpath %%F IN (*.*) DO ( set fname=%%~nF set subfname=!fname:~0,3! IF NOT "!subfname!" == "dat" echo "%%F" ) pause 

回声f.in和f.out将分开什么循环的概念,什么不循环用于for / f循环。

 ::Get the files seperated echo f.in>files_to_pass_through.txt echo f.out>>files_to_pass_through.txt for /F %%a in (files_to_pass_through.txt) do ( for /R %%b in (*.*) do ( if "%%a" NEQ "%%b" ( echo %%b>>dont_pass_through_these.txt ) ) ) ::I'm assuming the base name is the whole string "f". ::If I'm right then all the files begin with "f". ::So all you have to do is display "f". right? ::But that would be too easy. ::Let's do this the right way. for /f %%C in (dont_pass_through_these.txt) ::displays the filename and not the extention echo %~nC ) 

虽然你没有问,把命令传入f.in和f.out的好方法是…

 for /F %%D "tokens=*" in (dont_pass_through_these.txt) do ( for /F %%E in (%%D) do ( start /wait %%E ) ) 

指向所有Windows XP命令的链接 : 链接

如果我没有正确回答,我很抱歉。 这个问题很难读。