使用“for”循环迭代目录中的所有文件
Posted
技术标签:
【中文标题】使用“for”循环迭代目录中的所有文件【英文标题】:Iterate all files in a directory using a 'for' loop 【发布时间】:2022-01-13 19:21:40 【问题描述】:如何使用for
循环遍历目录中的每个文件?
我怎么知道某个条目是一个目录还是只是一个文件?
【问题讨论】:
假设您的意思是默认的 windows shell,我已经重新标记了您的帖子以更清楚一点 请同时说明您使用的 Windows 版本。 这应该分成两个独立的问题,因为它们是相互独立的。 【参考方案1】:这会列出当前目录中的所有文件(并且仅列出文件):
for /r %i in (*) do echo %i
此外,如果您在批处理文件中运行该命令,则需要将 % 符号加倍。
for /r %%i in (*) do echo %%i
(感谢@agnul)
【讨论】:
如果你不想递归使用这个,请确保你取出 /r 如果您只想在当前目录中回显文件名(而不是完整路径)及其扩展名(递归),您可以这样做:for /r %i in (*) do ( echo %~nxi )
。这个帖子也很有用:***.com/questions/112055/….
@Vaccano 是的,在 Do 之后,使用括号。 IE。做(回显 %i&del %i)。您还可以对多个命令使用“enter”而不是“&”。
如果您使用的是复制/移动等命令而不是回显,请确保正确引用路径。 for /r %%i in (*) do echo "%%i"
您显然需要使用单字母变量名。【参考方案2】:
遍历...
...当前目录中的文件: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/en-us/library/bb490890.aspx
【讨论】:
%file
和%subdir
只能是一个字符,即%f
、%s
。
“当前目录中的子目录”不起作用。我收到一个错误:此时 s 出乎意料【参考方案3】:
要遍历每个文件,可以使用 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
【讨论】:
啊,多行示例。谢谢! @Aaron Votre 如何结束循环? @nijogeorgep 您不必“结束”循环。在我的示例中,括号内的所有内容(echo 等)将为目录中的每个“*.txt”文件运行一次。我认为您正在寻找的答案可能在这里得到更好的解释:***.com/questions/1355791/… @Aaron Votre 我试图使用脚本运行一些 maven 命令,但它作为无限循环运行,所以我要求它。现在购买我在循环中添加了一个出口并解决了我的问题 @nijogeorgep 很高兴你知道了!【参考方案4】:从命令行和从批处理文件运行FOR
之间存在细微差别。在批处理文件中,您需要在每个变量引用前放置两个 %
字符。
从命令行:
FOR %i IN (*) DO ECHO %i
来自批处理文件:
FOR %%i IN (*) DO ECHO %%i
【讨论】:
【参考方案5】:这个for循环将列出目录中的所有文件。
pushd somedir
for /f "delims=" %%f in ('dir /b /a-d-h-s') do echo %%f
popd
"delims=" 对于显示带有空格的长文件名很有用....
'/b" 仅显示名称,不显示大小日期等。
关于 dir 的 /a 参数的一些知识。
对“/a”的任何使用都会列出所有内容,包括隐藏属性和系统属性。 “/ad”只会显示子目录,包括隐藏目录和系统目录。 “/a-d”参数消除了具有“目录”属性的内容。 "/a-d-h-s" 将显示所有内容,但具有 'D'irectory、'H'idden 'S'系统属性的条目。如果您在命令行中使用它,请删除“%”。
希望这会有所帮助。
【讨论】:
【参考方案6】:%1 指的是传入的第一个参数,不能在迭代器中使用。
试试这个:
@echo off
for %%i in (*.*) do echo %%i
【讨论】:
你是对的。我尝试在立即模式下检查 FOR 语法并将该行直接粘贴到忘记参数的答案中:-)【参考方案7】:在找到此参考之前,我很难让 jop 的答案使用绝对路径:https://ss64.com/nt/for_r.html
以下示例循环遍历由绝对路径指定的目录中的所有文件。
For /R C:\absoulte\path\ %%G IN (*.*) do (
Echo %%G
)
【讨论】:
【参考方案8】:遍历所有文件和文件夹您可以使用
for /F "delims=" %%a in ('dir /b /s') do echo %%a
要仅遍历所有文件夹而不是文件,那么您可以使用
for /F "delims=" %%a in ('dir /a:d /b /s') do echo %%a
/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
【讨论】:
【参考方案9】:for %1 in (*.*) do echo %1
在 cmd 中尝试“帮助”以获得完整指南
这是 XP 命令的指南。 http://www.ss64.com/nt/
【讨论】:
【参考方案10】:这是我在代码中使用 cmets 的方法。
我只是在刷怪技能,所以请原谅任何明显的错误。
我尝试在用户需要的地方稍作修改,尽可能地编写一个多合一的解决方案。
一些重要说明:如果您只想处理根目录文件和文件夹,只需将变量recursive
更改为FALSE
。否则,它会遍历所有文件夹和文件。
欢迎 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
【讨论】:
【参考方案11】:以下代码在当前目录中创建一个名为"AllFilesInCurrentDirectorylist.txt"的文件,其中包含当前目录中所有文件(Only Files)的列表。看看吧
dir /b /a-d > AllFilesInCurrentDirectorylist.txt
【讨论】:
【参考方案12】:也可以使用forfiles命令:
forfiles /s
并检查它是否是一个目录
forfiles /p c:\ /s /m *.* /c "cmd /c if @isdir==true echo @file is a directory"
【讨论】:
@isdir==true
必须是 @isdir==TRUE
【参考方案13】:
我会使用 vbscript (Windows Scripting Host),因为在批处理中我确定你无法分辨名称是文件还是目录。
在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
检查FileSystemObject on MSDN。
【讨论】:
我会使用 perl 来做到这一点。不幸的是,这不取决于我。 一些旧的应用程序?悲伤的事情。 一个白痴开发人员看到批处理文件并认为它们是解决我们所有问题的方法。 @Vhaerun Windows Script Host (WSH) 相对于 Perl 的一个优势是 WSH 预装在所有版本的 Windows 中,而 Perl 需要单独安装,这可能会也可能不会在所有情况下都是可行的选择。【参考方案14】:我使用带有 /L 选项的 xcopy 命令来获取文件名。因此,如果您想获取目录或子目录中的所有文件,您可以执行以下操作:
for /f "delims=" %%a IN ('xcopy "D:\*.pdf" c:\ /l') do echo %%a
我只是使用 c:\ 作为目标,因为它始终存在于 Windows 系统上并且它不会复制,所以没关系。如果您也想要子目录,请在最后使用 /s 选项。如果您出于其他原因需要它们,也可以使用 xcopy 的其他开关。
【讨论】:
【参考方案15】:试试这个来测试一个文件是否是一个目录:
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 的消息“找不到文件”进行测试”。
【讨论】:
【参考方案16】:试试这个:
::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 ..)
【讨论】:
【参考方案17】:就我而言,我必须删除临时文件夹下的所有文件和文件夹。所以这就是我最终这样做的方式。我必须运行两个循环,一个用于文件,一个用于文件夹。如果文件或文件夹的名称中有空格,那么您必须使用“”
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"
)
【讨论】:
以上是关于使用“for”循环迭代目录中的所有文件的主要内容,如果未能解决你的问题,请参考以下文章