Iterare tutti i file in una directory usando un ciclo 'for'


353

Come posso iterare su ogni file in una directory usando un forciclo?

E come potrei dire se una determinata voce è una directory o se è solo un file?


1
supponendo che tu intendessi la shell di Windows predefinita, ho ricodificato il tuo post per un po 'più di chiarezza
David Schmitt,

2
Si prega inoltre di specificare quale versione di Windows si sta utilizzando.
jop,

1
Questo dovrebbe essere diviso in due domande separate in quanto sono indipendenti l'una dall'altra.
julealgon,

Risposte:


493

Questo elenca tutti i file (e solo i file) nella directory corrente:

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

Inoltre, se si esegue quel comando in un file batch, è necessario raddoppiare i segni%.

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

(grazie @agnul)


73
Se non si desidera utilizzare questo in modo ricorsivo, assicurarsi di eliminare / r
jocull

28
Se si desidera solo fare eco i nomi dei file (non il percorso completo) con le loro estensioni nella directory corrente (ricorsivamente), si può fare in questo modo: for /r %i in (*) do ( echo %~nxi ). Anche questa discussione può essere davvero utile: stackoverflow.com/questions/112055/… .
Sk8erPeter,

2
@Vaccano sì, dopo il Do, usa la parentesi. Cioè (echo% i & del% i). Puoi anche usare "invio" anziché "&" per più comandi.
Jay,

2
Se stai usando comandi come copia / sposta piuttosto che eco, assicurati di citare il percorso correttamente. per / r %% i in (*) echo "%% i"
Soundararajan

2
Apparentemente devi usare nomi di variabili a lettera singola.
Álvaro González,

214

Scorrere attraverso ...

  • ... file nella directory corrente: for %f in (.\*) do @echo %f
  • ... subdir nella directory corrente: for /D %s in (.\*) do @echo %s
  • ... file nell'attuale e in tutti i sottodir: for /R %f in (.\*) do @echo %f
  • ... sottodirigi negli attuali e tutti i sottodir: for /R /D %s in (.\*) do @echo %s

Sfortunatamente non ho trovato alcun modo per scorrere contemporaneamente su file e sottodirectory.

Usa cygwin con il suo bash per molte più funzionalità.

A parte questo: hai notato che l'aiuto integrato di MS Windows è una grande risorsa per le descrizioni della sintassi della riga di comando di cmd?

Dai anche un'occhiata qui: http://technet.microsoft.com/en-us/library/bb490890.aspx


21
%filee %subdirpuò essere solo carattere lungo, cioè %f, %s.
Felix Dombek,

1
il 'sottodir nella directory corrente' non funziona. Ottengo un errore: s era imprevisto in questo momento
Migrate2Lazarus guarda il mio profilo il

78

Per scorrere su ogni file funzionerà un ciclo for:

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

Nel mio caso volevo anche il contenuto del file, il nome, ecc.

Ciò ha portato ad alcuni problemi e ho pensato che il mio caso d'uso potesse aiutare. Ecco un ciclo che legge le informazioni da ciascun file '.txt' in una directory e ti permette di fare qualcosa con esso (setx per esempio).

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

* Limitazione: val <= %% f otterrà solo la prima riga del file.


18
Ah, un esempio multilinea. Grazie per quello!
Nyerguds,

@Aaron Votre Come terminare un loop?
nijogeorgep,

@nijogeorgep Non devi "terminare" il ciclo. Nel mio esempio, tutto all'interno delle parentesi (eco, ecc.) Verrà eseguito una volta per ogni file '* .txt' nella directory. Penso che la risposta che stai cercando potrebbe essere meglio spiegata qui: stackoverflow.com/questions/1355791/…
Aaron Votre,

@Aaron Votre Stavo cercando di eseguire alcuni comandi maven usando lo script, ma funzionava come un ciclo infinito, quindi l'ho chiesto. Acquista ora Ho aggiunto un'uscita al mio loop e risolto il problema
nijogeorgep,

@nijogeorgep Sono contento che tu l'abbia capito!
Aaron Votre,

57

C'è una sottile differenza tra l'esecuzione FORdalla riga di comando e da un file batch. In un file batch, è necessario mettere due %caratteri davanti a ogni riferimento di variabile.

Da una riga di comando:

FOR %i IN (*) DO ECHO %i

Da un file batch:

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

44

Questo for-loop elencherà tutti i file in una directory.

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

"delims =" è utile per mostrare nomi di file lunghi con spazi al suo interno ....

"/ b" mostra solo i nomi, non le date delle dimensioni ecc.

Alcune cose da sapere su dir / a argomento.

  • Qualsiasi uso di "/ a" elenca tutto, inclusi gli attributi nascosti e di sistema.
  • "/ ad" mostrerebbe solo le sottodirectory, comprese quelle nascoste e di sistema.
  • L'argomento "/ ad" elimina il contenuto con l'attributo 'D'irectory.
  • "/ adhs" mostrerà tutto, ma le voci con l'attributo 'D'irectory,' H'idden 'S'ystem.

Se lo usi dalla riga di comando, rimuovi "%".

Spero che sia di aiuto.


10

% 1 si riferisce al primo argomento passato e non può essere utilizzato in un iteratore.

Prova questo:

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

Hai ragione. Ho provato in modalità immediata per verificare la sintassi FOR e ho incollato la linea direttamente nella risposta dimenticandomi dei parametri :-)
Axeman


4

Per scorrere tutti i file e le cartelle che è possibile utilizzare

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

Per scorrere tutte le cartelle solo non con i file, è possibile utilizzare

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

Dove /sdarà tutti i risultati in tutto l'albero della directory in profondità illimitata. Puoi saltare/s se si desidera scorrere il contenuto di quella cartella e non la sua sottocartella

Implementazione della ricerca nell'iterazione

Per scorrere i file e le cartelle con un determinato nome, è possibile cercare il nome e scorrere utilizzando il ciclo for

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

Per scorrere le cartelle / directory denominate in particolare e non i file , utilizzare /ADlo stesso comando

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

4

Ho avuto problemi a far funzionare la risposta di jop con un percorso assoluto fino a quando non ho trovato questo riferimento: https://ss64.com/nt/for_r.html

L'esempio seguente scorre tutti i file in una directory fornita dal percorso assoluto.

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

3

Il codice seguente crea un file denominato "AllFilesInCurrentDirectorylist.txt" nella directory corrente, che contiene l'elenco di tutti i file (solo file) nella directory corrente. Controlla

dir /b /a-d > AllFilesInCurrentDirectorylist.txt

3

Potrebbe anche usare il comando forfiles :

forfiles /s 

e controlla anche se si tratta di una directory

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

@isdir==truedeve essere@isdir==TRUE
psyklopz il

2

Vorrei usare vbscript (Windows Scripting Host), perché in batch sono sicuro che non si può dire che un nome è un file o una directory.

In vbs, può essere qualcosa del genere:

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

Controllare FileSystemObject su MSDN .


Avrei usato perl per fare questo. Sfortunatamente, non dipende da me.
Vhaerun,

Qualche vecchia applicazione? Cose tristi.
Biri,

Uno sviluppatore idiota ha visto i file batch e ha pensato che fossero la cura per tutti i nostri problemi.
Vhaerun,

1
@Vhaerun Un vantaggio di Windows Script Host (WSH) su Perl sarebbe che WSH è preinstallato con tutte le versioni di Windows, mentre Perl dovrebbe essere installato separatamente, il che potrebbe essere o meno un'opzione fattibile in tutti i casi.
Parampreet Dhatt,

2

Uso il comando xcopy con l'opzione / L per ottenere i nomi dei file. Quindi se vuoi ottenere una directory o tutti i file nella sottodirectory potresti fare qualcosa del genere:

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

Uso semplicemente c: \ come destinazione perché esiste sempre su sistemi Windows e non sta copiando, quindi non importa. se vuoi anche le sottodirectory usa solo l'opzione / s alla fine. Puoi anche usare gli altri switch di xcopy se ne hai bisogno per altri motivi.


2

Prova questo per verificare se un file è una directory:

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

Questo ti dirà solo se un file NON è una directory, il che sarà vero anche se il file non esiste, quindi assicurati di verificarlo prima se necessario. I punti di inserimento (^) vengono utilizzati per evitare i simboli di reindirizzamento e l'output dell'elenco file viene reindirizzato a NUL per impedirne la visualizzazione, mentre l'output dell'errore dell'elenco DIR viene reindirizzato all'output in modo da poter verificare il messaggio DIR "File non trovato ".


2

prova questo:

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

conta i file .msi ed .exe nella tua directory (e nella sottodirectory). Quindi fa anche la differenza tra cartelle e file come file eseguibili.

Aggiungi un'estensione (.pptx .docx ..) se devi filtrare altri file nel loop


1

Nel mio caso ho dovuto eliminare tutti i file e le cartelle sotto una cartella temporanea. Quindi è così che ho finito per farlo. Ho dovuto eseguire due loop uno per il file e uno per le cartelle. Se i file o le cartelle hanno spazi nei loro nomi, devi usare ""

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

Ecco il mio go con commenti nel codice.

Sto solo ripulendo con abilità da biatch, quindi perdona qualsiasi palese errore.

Ho provato a scrivere una soluzione tutto in uno nel miglior modo possibile con una piccola modifica dove l'utente lo richiede.

Alcune note importanti: basta cambiare la variabile recursivein FALSEse si desidera elaborare solo i file e le cartelle delle directory principali. Altrimenti, passa attraverso tutte le cartelle e i file.

C&C molto gradito ...

@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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.