Lặp lại tất cả các tệp trong một thư mục bằng vòng lặp 'for'


352

Làm thế nào tôi có thể lặp lại qua từng tệp trong một thư mục bằng cách sử dụng một forvòng lặp?

Và làm thế nào tôi có thể biết nếu một mục nhất định là một thư mục hoặc nếu nó chỉ là một tập tin?


1
giả sử bạn có nghĩa là vỏ cửa sổ mặc định, tôi đã thử lại bài đăng của bạn để rõ hơn một chút
David Schmitt

2
Vui lòng chỉ định phiên bản Windows bạn đang sử dụng.
jop

1
Điều này nên được chia thành hai câu hỏi riêng biệt vì chúng độc lập với nhau.
julealgon

Câu trả lời:


492

Điều này liệt kê tất cả các tệp (và chỉ các tệp) trong thư mục hiện tại:

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

Ngoài ra nếu bạn chạy lệnh đó trong một tệp bó, bạn cần nhân đôi dấu%.

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

(cảm ơn @agnul)


73
Nếu bạn không muốn sử dụng đệ quy này, hãy đảm bảo bạn lấy ra / r
jocull

28
Nếu bạn chỉ muốn lặp lại tên tệp (không phải đường dẫn đầy đủ) với các phần mở rộng của chúng trong thư mục hiện tại (đệ quy), bạn có thể làm như thế này : for /r %i in (*) do ( echo %~nxi ). Chủ đề này cũng có thể thực sự hữu ích: stackoverflow.com/questions/112055/ .
Sk8erPeter

2
@Vaccano có, sau khi làm, sử dụng dấu ngoặc đơn. Tức là (echo% i & del% i). Bạn cũng có thể sử dụng "enter" thay vì "&" cho nhiều lệnh.
Jay

2
Nếu bạn đang sử dụng các lệnh như sao chép / di chuyển thay vì echo, hãy đảm bảo rằng bạn trích dẫn đúng đường dẫn. cho / r %% i trong (*) thực hiện tiếng vang "%% i"
Soundararajan

2
Bạn rõ ràng cần phải sử dụng tên biến đơn.
Álvaro González

214

Lặp lại qua ...

  • ... tập tin trong thư mục hiện tại: for %f in (.\*) do @echo %f
  • ... các thư mục con trong thư mục hiện tại: for /D %s in (.\*) do @echo %s
  • ... Các tập tin hiện tại và tất cả các thư mục con: for /R %f in (.\*) do @echo %f
  • ... các thư mục con hiện tại và tất cả các thư mục con: for /R /D %s in (.\*) do @echo %s

Thật không may, tôi đã không tìm thấy bất kỳ cách nào để lặp lại các tập tin và thư mục con cùng một lúc.

Chỉ cần sử dụng cygwin với bash của nó để có nhiều chức năng hơn.

Ngoài ra, bạn có để ý rằng, trợ giúp xây dựng của MS Windows là một tài nguyên tuyệt vời để mô tả cú pháp dòng lệnh của cmd không?

Ngoài ra, hãy xem tại đây: http://technet.microsoft.com/en-us/l Library / bb490890.aspx


21
%file%subdirchỉ có thể là một ký tự dài, nghĩa là %f, %s.
Felix Dombek

1
các 'thư mục con trong thư mục hiện tại' không hoạt động. Tôi gặp lỗi: s bất ngờ vào lúc này
Migrate2Lazarus xem hồ sơ của tôi

78

Để lặp lại qua mỗi tệp, một vòng lặp for sẽ hoạt động:

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

Trong trường hợp của tôi, tôi cũng muốn nội dung tập tin, tên, vv

Điều này dẫn đến một vài vấn đề và tôi nghĩ trường hợp sử dụng của tôi có thể giúp ích. Đây là một vòng lặp đọc thông tin từ mỗi tệp '.txt' trong một thư mục và cho phép bạn làm điều gì đó với nó (ví dụ 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!"
)

* Giới hạn: val <= %% f sẽ chỉ nhận được dòng đầu tiên của tệp.


18
Ah, một ví dụ đa dòng. Cảm ơn vì điều đó!
Nyerguds

@Aaron Votre Làm thế nào để kết thúc một vòng lặp?
nijogeorgep

@nijogeorgep Bạn không cần phải "kết thúc" vòng lặp. Trong ví dụ của tôi, mọi thứ bên trong dấu ngoặc đơn, (echo, v.v.), sẽ được chạy một lần cho mỗi tệp '* .txt' trong thư mục. Tôi nghĩ rằng câu trả lời bạn đang tìm kiếm có thể được giải thích tốt hơn ở đây: stackoverflow.com/questions/1355791/ mẹo
Aaron Votre

@Aaron Votre Tôi đã cố chạy một số lệnh maven bằng cách sử dụng tập lệnh, nhưng nó đang chạy như một vòng lặp vô hạn, vì vậy tôi đã yêu cầu nó. Mua ngay Tôi đã thêm một lối thoát vào vòng lặp của mình và khắc phục sự cố của mình
nijogeorgep

@nijogeorgep Vui mừng bạn đã tìm ra nó!
Aaron Votre

57

Có một sự khác biệt tinh tế giữa việc chạy FORtừ dòng lệnh và từ một tệp bó. Trong một tệp bó, bạn cần đặt hai %ký tự trước mỗi tham chiếu biến.

Từ một dòng lệnh:

FOR %i IN (*) DO ECHO %i

Từ một tệp bó:

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

44

Vòng lặp for này sẽ liệt kê tất cả các tệp trong một thư mục.

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

"delims =" rất hữu ích để hiển thị tên tệp dài có khoảng trắng trong đó ....

'/ b "chỉ hiển thị tên, không phải ngày kích thước, v.v.

Một số điều cần biết về dir's / a argument.

  • Bất kỳ việc sử dụng "/ a" nào cũng sẽ liệt kê mọi thứ, bao gồm các thuộc tính hệ thống và ẩn.
  • "/ Quảng cáo" sẽ chỉ hiển thị các thư mục con, bao gồm các thư mục ẩn và hệ thống.
  • Đối số "/ quảng cáo" sẽ loại bỏ nội dung với thuộc tính 'D'irectory.
  • "/ adhs" sẽ hiển thị mọi thứ, nhưng các mục có thuộc tính 'D'irectory,' H'idden 'S'ystem.

Nếu bạn sử dụng điều này trên dòng lệnh, hãy xóa "%".

Hi vọng điêu nay co ich.


10

% 1 đề cập đến đối số đầu tiên được truyền vào và không thể được sử dụng trong một trình vòng lặp.

Thử cái này:

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

Bạn đúng. Tôi đã thử ở chế độ ngay lập tức để kiểm tra cú pháp FOR và dán thẳng dòng vào câu trả lời mà quên về các tham số :-)
Axeman

5
for %1 in (*.*) do echo %1

Hãy thử "GIÚP CHO" trong cmd để được hướng dẫn đầy đủ

Đây là hướng dẫn cho các lệnh XP. http://www.ss64.com/nt/


4

Để lặp qua tất cả các tệp và thư mục bạn có thể sử dụng

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

Để lặp qua tất cả các thư mục không chỉ với các tệp, sau đó bạn có thể sử dụng

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

Nơi /ssẽ cung cấp cho tất cả các kết quả trong suốt cây thư mục ở độ sâu không giới hạn. Bạn có thể bỏ qua /snếu bạn muốn lặp qua nội dung của thư mục đó chứ không phải thư mục con của họ

Thực hiện tìm kiếm trong vòng lặp

Để lặp qua một tệp và thư mụctên cụ thể, bạn có thể tìm kiếm tên và lặp lại bằng cách sử dụng vòng lặp

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

Để lặp qua một thư mục / thư mục có tên cụ thể và không phải tệp , sau đó sử dụng /ADtrong cùng một lệnh

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

4

Tôi gặp khó khăn khi câu trả lời của jop hoạt động với một đường dẫn tuyệt đối cho đến khi tôi tìm thấy tài liệu tham khảo này: https://ss64.com/nt/for_r.html

Ví dụ sau đây lặp qua tất cả các tệp trong một thư mục được cung cấp bởi đường dẫn tuyệt đối.

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

3

Đoạn mã sau tạo một tệp có tên "AllFilesInCienDirectorylist.txt" trong Thư mục hiện tại, chứa danh sách tất cả các tệp (Chỉ tệp) trong Thư mục hiện tại. Kiểm tra nó

dir /b /a-d > AllFilesInCurrentDirectorylist.txt

3

Nó cũng có thể sử dụng lệnh forfiles :

forfiles /s 

và cũng kiểm tra nếu nó là một thư mục

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

@isdir==truecần phải có@isdir==TRUE
psyklopz

2

Tôi sẽ sử dụng vbscript (Windows Scripting Host), vì trong đợt tôi chắc chắn bạn không thể biết tên đó là tệp hay thư mục.

Trong vbs, nó có thể là một cái gì đó như thế này:

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

Kiểm tra FileSystemObject trên MSDN .


Tôi đã sử dụng perl để làm điều này. Thật không may, nó không phụ thuộc vào tôi.
Vhaerun

Một số ứng dụng cũ? Những điều đáng buồn.
Biri

Một nhà phát triển ngốc đã xem các tệp hàng loạt và nghĩ rằng chúng là phương thuốc cho tất cả các vấn đề của chúng tôi.
Vhaerun

1
@Vhaerun Một ưu điểm của Windows Script Host (WSH) so với Perl là WSH được cài đặt sẵn với tất cả các phiên bản Windows, trong khi Perl sẽ cần phải được cài đặt riêng, có thể hoặc không phải là một tùy chọn khả thi trong mọi trường hợp.
Parampreet Dhatt

2

Tôi sử dụng lệnh xcopy với tùy chọn / L để lấy tên tệp. Vì vậy, nếu bạn muốn lấy một thư mục hoặc tất cả các tệp trong thư mục con, bạn có thể làm một cái gì đó như thế này:

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

Tôi chỉ sử dụng c: \ làm đích vì nó luôn tồn tại trên các hệ thống windows và nó không sao chép nên không thành vấn đề. nếu bạn muốn các thư mục con cũng chỉ cần sử dụng tùy chọn / s ở cuối. Bạn cũng có thể sử dụng các công tắc khác của xcopy nếu bạn cần chúng vì những lý do khác.


2

Hãy thử điều này để kiểm tra nếu một tập tin là một thư mục:

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

Điều này chỉ cho bạn biết liệu tệp KHÔNG phải là thư mục hay không, điều này cũng đúng nếu tệp không tồn tại, vì vậy hãy chắc chắn kiểm tra tệp đó trước nếu bạn cần. Các dấu mũ (^) được sử dụng để thoát các ký hiệu chuyển hướng và đầu ra danh sách tệp được chuyển hướng đến NUL để ngăn không hiển thị, trong khi đầu ra lỗi của danh sách DIR được chuyển hướng đến đầu ra để bạn có thể kiểm tra thông báo của DIR "Không tìm thấy tệp ".


2

thử cái này:

::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

nó đếm các tập tin .msi và .exe trong thư mục của bạn (và trong thư mục con). Vì vậy, nó cũng làm cho sự khác biệt giữa các thư mục và tập tin như các tệp thực thi.

Chỉ cần thêm tiện ích mở rộng (.pptx .docx ..) nếu bạn cần lọc các tệp khác trong vòng lặp


1

Trong trường hợp của tôi, tôi đã phải xóa tất cả các tệp và thư mục bên dưới một thư mục tạm thời. Vì vậy, đây là cách tôi đã làm nó. Tôi đã phải chạy hai vòng một cho tập tin và một cho các thư mục. Nếu tệp hoặc thư mục có khoảng trắng trong tên của chúng thì bạn phải sử dụng ""

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

Đây là ý kiến ​​của tôi với các ý kiến ​​trong mã.

Tôi chỉ cần cải thiện bằng các kỹ năng biatch để tha thứ cho bất kỳ lỗi trắng trợn nào.

Tôi đã cố gắng viết một giải pháp tất cả trong một cách tốt nhất có thể với một chút sửa đổi trong đó người dùng yêu cầu nó.

Một số lưu ý quan trọng: Chỉ cần thay đổi biến recursivethành FALSEnếu bạn chỉ muốn các tệp và thư mục gốc được xử lý. Nếu không, nó đi qua tất cả các thư mục và tập tin.

C & C hoan nghênh nhất ...

@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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.