Iterieren Sie alle Dateien in einem Verzeichnis mit einer 'for'-Schleife

352

Wie kann ich mit einer forSchleife über jede Datei in einem Verzeichnis iterieren ?

Und wie kann ich feststellen, ob ein bestimmter Eintrag ein Verzeichnis oder nur eine Datei ist?

Vhaerun
quelle
1
Angenommen, Sie meinten die Standard-Windows-Shell, habe ich Ihren Beitrag für ein bisschen mehr Klarheit neu markiert
David Schmitt
2
Bitte geben Sie auch an, welche Windows-Version Sie verwenden.
Jop
1
Dies sollte in zwei separate Fragen aufgeteilt werden, da diese unabhängig voneinander sind.
Julealgon

Antworten:

492

Dies listet alle Dateien (und nur die Dateien) im aktuellen Verzeichnis auf:

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

Wenn Sie diesen Befehl in einer Batchdatei ausführen, müssen Sie die% -Zeichen verdoppeln.

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

(danke @agnul)

jop
quelle
73
Wenn Sie dies nicht rekursiv verwenden möchten, stellen Sie sicher, dass Sie den / r
jocull
28
Wenn Sie nur die Dateinamen (nicht den vollständigen Pfad) mit ihren Erweiterungen im aktuellen Verzeichnis (rekursiv) wiedergeben möchten, können Sie dies folgendermaßen tun : for /r %i in (*) do ( echo %~nxi ). Dieser Thread kann auch sehr nützlich sein: stackoverflow.com/questions/112055/… .
Sk8erPeter
2
@Vaccano ja, nach dem Do Klammer verwenden. Dh tun (echo% i & del% i). Sie können auch "enter" anstelle von "&" für mehrere Befehle verwenden.
Jay
2
Wenn Sie Befehle wie Kopieren / Verschieben anstelle von Echo verwenden, stellen Sie sicher, dass Sie den Pfad richtig angeben. für / r %% i in (*) echo "%% i"
Soundararajan
2
Sie müssen anscheinend einzelne Buchstaben Variablennamen verwenden.
Álvaro González
214

Iterieren durch ...

  • ... Dateien im aktuellen Verzeichnis: for %f in (.\*) do @echo %f
  • ... Unterverzeichnisse im aktuellen Verzeichnis: for /D %s in (.\*) do @echo %s
  • ... Dateien in aktuellen und allen Unterverzeichnissen: for /R %f in (.\*) do @echo %f
  • ... Unterverzeichnisse in aktuellen und allen Unterverzeichnissen: for /R /D %s in (.\*) do @echo %s

Leider habe ich keine Möglichkeit gefunden, Dateien und Unterverzeichnisse gleichzeitig zu durchlaufen.

Verwenden Sie einfach Cygwin mit seiner Bash für viel mehr Funktionalität.

Abgesehen davon: Haben Sie bemerkt, dass die eingebaute Hilfe von MS Windows eine großartige Ressource für Beschreibungen der Befehlszeilensyntax von cmd ist?

Schauen Sie auch hier: http://technet.microsoft.com/en-us/library/bb490890.aspx

Marco
quelle
21
%fileund %subdirkann nur ein Zeichen lang sein, dh %f, %s.
Felix Dombek
1
Die 'Unterverzeichnisse im aktuellen Verzeichnis' funktionieren nicht. Ich erhalte eine Fehlermeldung: s war zu diesem Zeitpunkt unerwartet
Migrate2Lazarus siehe mein Profil
78

Um jede Datei zu durchlaufen, funktioniert eine for-Schleife:

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

In meinem Fall wollte ich auch den Inhalt, den Namen usw. der Datei.

Dies führte zu einigen Problemen und ich dachte, mein Anwendungsfall könnte helfen. Hier ist eine Schleife, die Informationen aus jeder '.txt'-Datei in einem Verzeichnis liest und es Ihnen ermöglicht, etwas damit zu tun (z. B. 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!"
)

* Einschränkung: val <= %% f erhält nur die erste Zeile der Datei.

Aaron Votre
quelle
18
Ah, ein mehrzeiliges Beispiel. Dank dafür!
Nyerguds
@ Aaron Votre Wie beende ich eine Schleife?
Nijogeorgep
@nijogeorgep Du musst die Schleife nicht "beenden". In meinem Beispiel wird alles in den Klammern (Echo usw.) einmal für jede '* .txt'-Datei im Verzeichnis ausgeführt. Ich denke, die Antwort, die Sie suchen, könnte hier besser erklärt werden: stackoverflow.com/questions/1355791/…
Aaron Votre
@ Aaron Votre Ich habe versucht, einige Maven-Befehle mithilfe eines Skripts auszuführen, aber es wurde als Endlosschleife ausgeführt. Also habe ich danach gefragt. Jetzt kaufen Ich habe einen Exit zu meiner Schleife hinzugefügt und mein Problem
behoben
@nijogeorgep Schön, dass du es herausgefunden hast!
Aaron Votre
57

Es gibt einen subtilen Unterschied zwischen der Ausführung FORüber die Befehlszeile und über eine Batchdatei. In eine Batch-Datei müssen Sie zwei einfügen% Zeichen vor jede Variablenreferenz setzen.

Über eine Befehlszeile:

FOR %i IN (*) DO ECHO %i

Aus einer Batch-Datei:

FOR %%i IN (*) DO ECHO %%i
Aphorie
quelle
44

Diese for-Schleife listet alle Dateien in einem Verzeichnis auf.

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

"delims =" ist nützlich, um lange Dateinamen mit Leerzeichen anzuzeigen ....

'/ b "zeige nur Namen, keine Größendaten usw ..

Einige Dinge, die Sie über dir's / a argument wissen sollten.

  • Jede Verwendung von "/ a" würde alles auflisten, einschließlich versteckter und Systemattribute.
  • "/ ad" zeigt nur Unterverzeichnisse an, einschließlich versteckter und Systemverzeichnisse.
  • Das Argument "/ ad" entfernt Inhalte mit dem Attribut 'D'irectory'.
  • "/ adhs" zeigt alles außer Einträgen mit dem Attribut 'D'irectory', 'H'idden' S'ystem.

Wenn Sie dies in der Befehlszeile verwenden, entfernen Sie ein "%".

Hoffe das hilft.

Jay
quelle
10

% 1 bezieht sich auf das erste übergebene Argument und kann nicht in einem Iterator verwendet werden.

Versuche dies:

@echo off
for %%i in (*.*) do echo %%i
Sam Meldrum
quelle
Du hast recht. Ich habe im Sofortmodus versucht, die FOR-Syntax zu überprüfen und die Zeile direkt in die Antwort eingefügt, wobei Parameter vergessen wurden :-)
Axeman
5
for %1 in (*.*) do echo %1

Versuchen Sie "HILFE FÜR" in cmd für eine vollständige Anleitung

Dies ist die Anleitung für XP-Befehle. http://www.ss64.com/nt/

Axeman
quelle
4

Zum Durchlaufen aller Dateien und Ordner, die Sie verwenden können

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

Um alle Ordner nur nicht mit Dateien zu durchlaufen , können Sie verwenden

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

Wo /swerden alle Ergebnisse im gesamten Verzeichnisbaum in unbegrenzter Tiefe angezeigt. Du kannst überspringen/s wenn Sie den Inhalt dieses Ordners und nicht dessen Unterordner durchlaufen möchten

Implementierung in Iteration implementieren

Um bestimmte benannte Dateien und Ordner zu durchlaufen , können Sie nach dem Namen suchen und mit der for-Schleife iterieren

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

Verwenden Sie denselben Befehl, um bestimmte benannte Ordner / Verzeichnisse und keine Dateien zu durchlaufen/AD

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

Ich hatte Probleme, die Antwort von jop dazu zu bringen, mit einem absoluten Pfad zu arbeiten, bis ich diese Referenz fand: https://ss64.com/nt/for_r.html

Im folgenden Beispiel werden alle Dateien in einem Verzeichnis durchlaufen, das durch den absoluten Pfad angegeben wird.

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

Der folgende Code erstellt eine Datei mit dem Namen "AllFilesInCurrentDirectorylist.txt" im aktuellen Verzeichnis, die die Liste aller Dateien (nur Dateien) im aktuellen Verzeichnis enthält. Hör zu

dir /b /a-d > AllFilesInCurrentDirectorylist.txt
Ankur
quelle
3

Es könnte auch den Befehl forfiles verwenden :

forfiles /s 

und überprüfen Sie auch, ob es sich um ein Verzeichnis handelt

forfiles /p c:\ /s /m *.* /c "cmd /c if @isdir==true echo @file is a directory"
Max
quelle
@isdir==truemuss sein@isdir==TRUE
psyklopz
2

Ich würde vbscript (Windows Scripting Host) verwenden, da Sie im Batch sicher nicht sagen können, dass ein Name eine Datei oder ein Verzeichnis ist.

In vbs kann es so etwas sein:

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

Überprüfen Sie FileSystemObject auf MSDN .

Biri
quelle
Ich hätte Perl benutzt, um das zu tun. Leider liegt es nicht an mir.
Vhaerun
Eine alte Anwendung? Traurige Dinge.
Biri
Ein idiotischer Entwickler sah Batch-Dateien und dachte, dass sie das Heilmittel für all unsere Probleme seien.
Vhaerun
1
@Vhaerun Ein Vorteil von Windows Script Host (WSH) gegenüber Perl besteht darin, dass WSH mit allen Windows-Versionen vorinstalliert ist, während Perl separat installiert werden muss, was in allen Fällen eine praktikable Option sein kann oder nicht.
Parampreet Dhatt
2

Ich verwende den Befehl xcopy mit der Option / L, um die Dateinamen abzurufen. Wenn Sie also entweder ein Verzeichnis oder alle Dateien im Unterverzeichnis abrufen möchten, können Sie Folgendes tun:

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

Ich verwende nur das c: \ als Ziel, da es auf Windows-Systemen immer vorhanden ist und nicht kopiert wird, sodass es keine Rolle spielt. Wenn Sie auch die Unterverzeichnisse verwenden möchten, verwenden Sie am Ende einfach die Option / s. Sie können auch die anderen Schalter von xcopy verwenden, wenn Sie sie aus anderen Gründen benötigen.

Knoots
quelle
2

Versuchen Sie dies, um zu testen, ob eine Datei ein Verzeichnis ist:

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

Hier erfahren Sie nur, ob eine Datei KEIN Verzeichnis ist. Dies gilt auch, wenn die Datei nicht vorhanden ist. Überprüfen Sie dies daher bei Bedarf zuerst. Die Carets (^) werden verwendet, um die Umleitungssymbole zu umgehen, und die Ausgabe der Dateiliste wird an NUL umgeleitet, um zu verhindern, dass sie angezeigt wird, während die Fehlerausgabe der DIR-Liste an die Ausgabe umgeleitet wird, damit Sie anhand der DIR-Meldung "Datei nicht gefunden" testen können ".

sugerfunk
quelle
2

Versuche dies:

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

Es zählt MSI- und EXE-Dateien in Ihrem Verzeichnis (und im Unterverzeichnis). Es macht also auch den Unterschied zwischen Ordnern und Dateien als ausführbare Dateien.

Fügen Sie einfach eine Erweiterung (.pptx .docx ..) hinzu, wenn Sie andere Dateien in der Schleife filtern müssen

Kleines Pony
quelle
1

In meinem Fall musste ich alle Dateien und Ordner unter einem temporären Ordner löschen. So kam ich dazu. Ich musste zwei Schleifen ausführen, eine für Datei und eine für Ordner. Wenn Dateien oder Ordner Leerzeichen in ihren Namen haben, müssen Sie "" verwenden

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"
)
Sam B.
quelle
1

Hier ist mein Einstieg mit Kommentaren im Code.

Ich werde nur durch Biatch-Fähigkeiten aufgefrischt, also verzeihen Sie alle offensichtlichen Fehler.

Ich habe versucht, eine All-in-One-Lösung so gut wie möglich mit einer kleinen Änderung zu schreiben, wo der Benutzer sie benötigt.

Einige wichtige Hinweise: Ändern Sie die Variable einfach recursivein, FALSEwenn nur die Stammverzeichnisdateien und -ordner verarbeitet werden sollen. Andernfalls werden alle Ordner und Dateien durchsucht.

C & C herzlich willkommen ...

@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
Ste
quelle