使用“ for”循环遍历目录中的所有文件


351

如何使用for循环遍历目录中的每个文件?

我怎么知道某个条目是目录还是仅仅是文件?


1
假设你的意思是默认的Windows外壳,我已经重新标记您的文章更加清晰的一点
戴维·施密特

2
还请指定您使用的Windows版本。
08年

1
这应分为两个独立的问题,因为它们彼此独立。
julealgon

Answers:


491

这将列出当前目录中的所有文件(并且仅列出文件):

for /r %i in (*) do echo %i

另外,如果您在批处理文件中运行该命令,则需要将%符号加倍。

for /r %%i in (*) do echo %%i

(感谢@agnul)


73
如果您不想递归使用此功能,请确保删除/ r
jocull 2010年

28
如果您只想(递归地)回显当前目录中的文件名(而不是完整路径)及其扩展名,则可以执行以下操作:for /r %i in (*) do ( echo %~nxi )。这个线程也真的很有用:stackoverflow.com/questions/112055/…
Sk8erPeter

2
@Vaccano是的,在执行之后,请使用括号。即(回显%i&del%i)。您也可以对多个命令使用“ enter”而不是“&”。
2014年

2
如果使用的命令是复制/移动而不是回显,请确保正确引用路径。(*)中的/ r %% i做回显“ %% i”
Soundararajan 2014年

2
您显然需要使用单字母变量名称。
阿瓦罗·冈萨雷斯(

214

遍历...

  • ...当前目录中的文件: for %f in (.\*) do @echo %f
  • ...当前目录中的子目录: for /D %s in (.\*) do @echo %s
  • ...当前目录和所有子目录中的文件: for /R %f in (.\*) do @echo %f
  • ...当前和所有子目录中的子目录: for /R /D %s in (.\*) do @echo %s

不幸的是,我没有找到任何方法可以同时遍历文件和子目录。

只需将cygwin及其bash用于更多功能即可。

除此之外:您是否注意到,MS Windows的内置帮助是描述cmd命令行语法的重要资源?

也可以在这里查看:http : //technet.microsoft.com/zh-cn/library/bb490890.aspx


21
%file并且%subdir只能是一个字符长,即%f%s
Felix Dombek

1
“当前目录中的子目录”不起作用。我收到一个错误:s目前是意外的
Migrate2Lazarus请参阅我的个人资料,2016年

78

要遍历每个文件,一个for循环将起作用:

for %%f in (directory\path\*) do ( something_here )

就我而言,我还想要文件内容,名称等。

这导致了一些问题,我认为我的用例可能会有所帮助。这是一个循环,它从目录中的每个“ .txt”文件中读取信息,并允许您对其进行操作(例如setx)。

@ECHO OFF
setlocal enabledelayedexpansion
for %%f in (directory\path\*.txt) do (
  set /p val=<%%f
  echo "fullname: %%f"
  echo "name: %%~nf"
  echo "contents: !val!"
)

*限制:val <= %% f将仅获得文件的第一行。


18
嗯,多行示例。感谢那!
Nyerguds '16

@Aaron Votre如何结束循环?
nijogeorgep,

@nijogeorgep您不必“结束”循环。在我的示例中,括号内的所有内容(echo等)将针对目录中的每个“ * .txt”文件运行一次。我认为你正在寻找可能的答案在这里更好地解释:stackoverflow.com/questions/1355791/...
亚伦VOTRE

@Aaron Votre我试图使用脚本运行一些Maven命令,但是它以无限循环运行,所以我要求它。立即购买,我在循环中添加了一个出口并修复了我的问题
nijogeorgep

@nijogeorgep很高兴您知道了!
亚伦·沃特

57

FOR从命令行运行和从批处理文件运行之间存在细微的差异。在批处理文件中,您需要%在每个变量引用的前面放置两个字符。

从命令行:

FOR %i IN (*) DO ECHO %i

从批处理文件:

FOR %%i IN (*) DO ECHO %%i

44

此for循环将列出目录中的所有文件。

pushd somedir
for /f "delims=" %%f in ('dir /b /a-d-h-s') do echo %%f
popd

“ delims =”可用于显示长文件名并带有空格...。

'/ b“仅显示名称,不显示大小日期等。

关于dir的/ a参数要了解的一些事情。

  • 任何使用“ / a”都会列出所有内容,包括隐藏属性和系统属性。
  • “ / ad”将仅显示子目录,包括隐藏目录和系统目录。
  • “ / ad”参数消除具有'D'irectory属性的内容。
  • “ / adhs”将显示所有内容,但条目带有'D'irectory,'H'idden'S'ystem属性。

如果在命令行上使用此命令,请删除“%”。

希望这可以帮助。


10

%1引用传入的第一个参数,不能在迭代器中使用。

尝试这个:

@echo off
for %%i in (*.*) do echo %%i

你是对的。我已经尝试在即时模式下检查FOR语法并将行直接粘贴到答案中,而忘记了参数:-)
Axeman


4

遍历所有文件和文件夹,您可以使用

for /F "delims=" %%a in ('dir /b /s') do echo %%a

仅遍历所有文件夹而不是遍历所有文件,则可以使用

for /F "delims=" %%a in ('dir /a:d /b /s') do echo %%a

where /s将无限深度地遍历整个目录树中的所有结果。/s如果要遍历该文件夹的内容而不是其子文件夹,则可以跳过

在迭代中实现搜索

遍历特定的命名文件和文件夹,您可以搜索名称并使用for循环进行遍历

for /F "delims=" %%a in ('dir "file or folder name" /b /s') do echo %%a

遍历特定的命名文件夹/目录而不是文件,然后/AD在同一命令中使用

for /F "delims=" %%a in ('dir "folder name" /b /AD /s') do echo %%a

4

在找到以下参考之前,我很难获得jop的答案以使用绝对路径工作:https ://ss64.com/nt/for_r.html

下面的示例循环浏览绝对路径给定目录中的所有文件。

For /R C:\absoulte\path\ %%G IN (*.*) do (
  Echo %%G
)

3

以下代码在当前目录中创建一个名为“ AllFilesInCurrentDirectorylist.txt”的文件,其中包含当前目录中所有文件(仅文件)的列表。一探究竟

dir /b /a-d > AllFilesInCurrentDirectorylist.txt

3

它也可以使用forfiles命令:

forfiles /s 

并检查它是否是目录

forfiles /p c:\ /s /m *.* /c "cmd /c if @isdir==true echo @file is a directory"

@isdir==true需要是@isdir==TRUE
psyklopz 2015年

2

我将使用vbscript(Windows脚本宿主),因为在批处理中,我确定您无法确定名称是文件还是目录。

在vbs中,可能是这样的:

Dim fileSystemObject
Set fileSystemObject = CreateObject("Scripting.FileSystemObject")

Dim mainFolder
Set mainFolder = fileSystemObject.GetFolder(myFolder)

Dim files
Set files = mainFolder.Files

For Each file in files
...
Next

Dim subFolders
Set subFolders = mainFolder.SubFolders

For Each folder in subFolders
...
Next

在MSDN上检查FileSystemObject


我会用perl做到这一点。不幸的是,这不取决于我。
Vhaerun

一些旧的应用程序?可悲的事情。
比里

一位白痴的开发人员看到了批处理文件,认为它们是解决我们所有问题的方法。
Vhaerun

1
@Vhaerun Windows脚本宿主(WSH)与Perl相比的一个优点是WSH随Windows的所有版本一起预装,而Perl需要单独安装,这在所有情况下可能是可行的,也可能不是可行的选择。
Parampreet Dhatt

2

我将xcopy命令与/ L选项一起使用来获取文件名。因此,如果要获取目录或子目录中的所有文件,可以执行以下操作:

for /f "delims=" %%a IN ('xcopy "D:\*.pdf" c:\ /l') do echo %%a

我只是将c:\用作目标,因为它始终存在于Windows系统上,并且不会复制,因此没有关系。如果您也想要子目录,只需在末尾使用/ s选项。如果出于其他原因需要它们,也可以使用xcopy的其他开关。


2

尝试执行以下操作以测试文件是否为目录:

FOR /F "delims=" %I IN ('DIR /B /AD "filename" 2^>^&1 ^>NUL') DO IF "%I" == "File Not Found" ECHO Not a directory

这只会告诉您文件是否不是目录,如果文件不存在,这也将成立,因此请确保首先检查该目录。脱字符号(^)用于转义重定向符号,文件列表输出重定向到NUL以防止其显示,而DIR列表的错误输出重定向到输出,因此您可以对DIR的消息“找不到文件”进行测试”。


2

尝试这个:

::Example directory
set SetupDir=C:\Users

::Loop in the folder with "/r" to search in recursive folders, %%f being a loop ::variable 
for /r "%SetupDir%" %%f in (*.msi *.exe) do set /a counter+=1

echo there are %counter% files in your folder

它计算目录(和子目录)中的.msi和.exe文件。因此,这也使文件夹和文件作为可执行文件有所不同。

如果您需要在循环中过滤其他文件,只需添加扩展名(.pptx .docx ..)


1

以我为例,我必须删除临时文件夹下的所有文件和文件夹。所以这就是我最终做的方式。我不得不运行两个循环,一个用于文件,一个用于文件夹。如果文件或文件夹的名称中包含空格,则必须使用“”

cd %USERPROFILE%\AppData\Local\Temp\
rem files only
for /r %%a in (*) do (
echo deleting file "%%a" ...
if exist "%%a" del /s /q "%%a"
)
rem folders only
for /D %%a in (*) do (
echo deleting folder "%%a" ...
if exist "%%a" rmdir /s /q "%%a"
)

1

这是我在代码中的注释。

我只是通过biatch技巧来复习,所以请原谅任何明显的错误。

我试图在用户需要的地方进行一些修改,以尽力而为地编写一个全解决方案。

一些重要的注意事项:只需将变量更改recursiveFALSE,如果你只是想处理的根目录下的文件和文件夹。否则,它将遍历所有文件夹和文件。

C&C最欢迎...

@echo off
title %~nx0
chcp 65001 >NUL
set "dir=c:\users\%username%\desktop"
::
:: Recursive Loop routine - First Written by Ste on - 2020.01.24 - Rev 1
::
setlocal EnableDelayedExpansion
rem THIS IS A RECURSIVE SOLUTION [ALBEIT IF YOU CHANGE THE RECURSIVE TO FALSE, NO]
rem By removing the /s switch from the first loop if you want to loop through
rem the base folder only.
set recursive=TRUE
if %recursive% equ TRUE ( set recursive=/s ) else ( set recursive= )
endlocal & set recursive=%recursive%
cd /d %dir%
echo Directory %cd%
for %%F in ("*") do (echo    → %%F)                                 %= Loop through the current directory. =%
for /f "delims==" %%D in ('dir "%dir%" /ad /b %recursive%') do (    %= Loop through the sub-directories only if the recursive variable is TRUE. =%
  echo Directory %%D
  echo %recursive% | find "/s" >NUL 2>NUL && (
    pushd %%D
    cd /d %%D
    for /f "delims==" %%F in ('dir "*" /b') do (                      %= Then loop through each pushd' folder and work on the files and folders =%
      echo %%~aF | find /v "d" >NUL 2>NUL && (                        %= This will weed out the directories by checking their attributes for the lack of 'd' with the /v switch therefore you can now work on the files only. =%
      rem You can do stuff to your files here.
      rem Below are some examples of the info you can get by expanding the %%F variable.
      rem Uncomment one at a time to see the results.
      echo    → %%~F           &rem expands %%F removing any surrounding quotes (")
      rem echo    → %%~dF          &rem expands %%F to a drive letter only
      rem echo    → %%~fF          &rem expands %%F to a fully qualified path name
      rem echo    → %%~pF          &rem expands %%A to a path only
      rem echo    → %%~nF          &rem expands %%F to a file name only
      rem echo    → %%~xF          &rem expands %%F to a file extension only
      rem echo    → %%~sF          &rem expanded path contains short names only
      rem echo    → %%~aF          &rem expands %%F to file attributes of file
      rem echo    → %%~tF          &rem expands %%F to date/time of file
      rem echo    → %%~zF          &rem expands %%F to size of file
      rem echo    → %%~dpF         &rem expands %%F to a drive letter and path only
      rem echo    → %%~nxF         &rem expands %%F to a file name and extension only
      rem echo    → %%~fsF         &rem expands %%F to a full path name with short names only
      rem echo    → %%~dp$dir:F    &rem searches the directories listed in the 'dir' environment variable and expands %%F 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
      rem echo    → %%~ftzaF       &rem expands %%F to a DIR like output line
      )
      )
    popd
    )
  )
echo/ & pause & cls
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.