如何循环通过文件匹配通配符在批处理文件

我有一组基本文件名,每个名称'f'对应两个文件,'f.in'和'f.out'。我想写一个批处理文件(在Windows XP中),它通过所有的文件名,对于每一个它应该:

  • 显示基名'f'
  • 在'f.in'上执行一个动作
  • 在'f.out'上执行另一个操作

除了搜索*之外,我没有任何方法来列出基本文件名集。例如In(或*.out)。

353180 次浏览

在我看来,最简单的方法是使用一个for循环,调用第二个批处理文件进行处理,将基本名称传递给第二个文件。

根据for /?帮助,basename可以使用漂亮的~n选项提取。因此,基本脚本将如下所示:

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

然后,在过程中。Cmd命令,假设%0包含基本名称并相应执行。例如:

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

在一个脚本中可能有更好的方法来做到这一点,但我一直不清楚如何在批处理文件中的单个for循环中提取多个命令。

编辑:太棒了!我不知道为什么错过了文档中显示你可以在FOR循环中做多行块的那一页。我现在要回去重写一些批处理文件……

在MS服务器中有一个常用的工具(据我所知)叫做forfiles:

上面的链接包含帮助以及微软下载页面的链接。

你可以使用这一行来打印桌面的内容:

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

一旦你有了%%I变量,就很容易对它执行命令(只需用你的程序替换单词echo)

此外,FOR变量引用的替换也得到了增强 您现在可以使用以下可选语法:

%~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 (directory with \)
%~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

https://ss64.com/nt/syntax-args.html

在上面的例子中,%I和PATH可以替换为其他有效的 值。%~语法以一个有效的FOR变量名结束。 选择大写的变量名,如%I,使其更具可读性和 避免与修饰符混淆,修饰符不区分大小写

你可以通过输入FOR /?来获得完整的文档

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

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

%%~nf是一个替换修饰符,它只将%f展开为一个文件名。 在https://technet.microsoft.com/en-us/library/bb490909.aspx(页面中间)或下一个答案中查看其他修饰符

扩展内森 post。以下将在一个批处理文件中完成工作批次。

@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

下面的代码过滤以给定子字符串开头的文件名。它可以通过subfname子字符串提取和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

当在for /f循环中使用时,回显f.in和f.out将分离循环和不循环的概念。

::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命令的链接:链接

如果我没有回答正确,我很抱歉。这个问题对我来说很难理解。