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


193

我有一组基本文件名,每个名称'f'都有两个文件,'f.in'和'f.out'。我想编写一个批处理文件(在Windows XP中),它遍历所有文件名,每个文件名都应:

  • 显示基本名称“ f”
  • 对“ f.in”执行操作
  • 对“ f.out”执行其他操作

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


10
我真的不希望在111/0票后成为这个人,但您的问题没有显示任何reasearch whatsoeaver
phil294 '16

Answers:


292

假设您有两个程序来处理两个文件,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/zh-cn/library/bb490909.aspx(在页面中间)或在下一个答案中的其他修饰符。


47
如果在命令行上输入单个'%'。我知道OP不会询问命令行,但这是我在Google搜索顶部出现此问题时要搜索的内容。其他人可能会喜欢这一点。
杰森

2
您能解释一下语法吗?声明%%f了循环变量,为什么%%~nf以后再使用呢?
上校惊慌

6
@ColonelPanic-有一些~修饰符可以执行操作,例如在我的示例中,只需获取文件名即可。这是我的习惯,以防万一*。有这些修饰符的少数(中途下页):microsoft.com/resources/documentation/windows/xp/all/proddocs/...
吉姆·巴克

如果文件和目录中有空格怎么办?
BKSpurgeon '16

3
另外,请注意%% f变量必须为单个字母-如果尝试使用易读且有意义的内容,则会出现错误的错误消息。
Bruce Dawson

90

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

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 /?


这似乎不起作用。 %%I was unexpected at this time.
布拉德(Brad)2013年

4
@Brad,如果您在命令行中使用此命令(而不是在批处理文件中),则使用%I代替%%I
doubleDown

1
比接受的答案好得多。答案中包含的所有标记/修饰符,而不是第三方网站(没人想单击您的链接,Louis
JustCarty

5

如我所见,最简单的方法是使用for循环,该循环调用第二个批处理文件进行处理,并将第二个文件的基本名称传递给该文件。

根据for /?帮助,可以使用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

在一个脚本中可能有更好的方法来执行此操作,但是对于如何在批处理文件的单个for循环中提取多个命令,我一直有些困惑。

编辑:太棒了!我以某种方式错过了文档中显示可以在FOR循环中执行多行块的页面。我现在必须回去重写一些批处理文件...


4

Nathans帖子上扩展。下面将在一个批处理文件中完成工作。

@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

3

据我所记得,MS Server中通常使用一种称为forfiles的工具

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


1

下面的代码过滤以给定子字符串开头的文件名。通过处理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

0

回显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命令的链接link

如果无法正确回答,我深表歉意。这个问题对我来说很难读。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.