Batch di Windows: chiamare più di un comando in un ciclo FOR?


124

È possibile nel file batch di Windows chiamare più di un comando in un singolo FOR ciclo? Diciamo ad esempio che voglio stampare il nome del file e dopo eliminarlo:

@ECHO OFF
FOR /r %%X IN (*.txt) DO (ECHO %%X DEL %%X)
REM the line above is invalid syntax.

So che in questo caso potrei risolverlo facendo due distinti cicli FOR: uno per mostrare il nome e uno per cancellare il file, ma è possibile farlo in un solo loop?

Risposte:


117
FOR /r %%X IN (*) DO (ECHO %%X & DEL %%X)

2
In realtà, penso che le parentesi non siano necessarie. for %i in (1 2 3) do echo %i & echo foostampa quello che mi aspetto: "1", "foo", "2", "foo", "3", "foo" (su righe separate).
bk1e

Non dovrebbe essere &&piuttosto che &?
jww

9
@jww &&fallirà se il primo comando fallisce, &eseguirà il secondo comando a prescindere.
yyny

Se questa soluzione fa un errore di sintassi per te, controlla se hai una DOparentesi senza caratteri di escape tra le parentesi. Puoi sfuggirgli aggiungendo un ^a.
Константин Ван

199

L'uso &va bene per i comandi brevi, ma quella singola riga può diventare molto lunga molto rapidamente. Quando ciò accade, passa alla sintassi multilinea.

FOR /r %%X IN (*.txt) DO (
    ECHO %%X
    DEL %%X
)

Posizionamento di (e )questioni. Le parentesi tonde dopo DOdevono essere posizionate sulla stessa riga, altrimenti il ​​file batch non sarà corretto.

Vedere if /?|find /V ""per i dettagli.


12
Questa soluzione sembra pulita e leggibile. Vorrei inoltre avvertire qualsiasi programmatore che utilizza questa soluzione che la parentesi tonda dopo la DOriga NON deve essere posizionata nella riga successiva altrimenti frena il file batch. Nel codice, quando scrivo un ciclo for, di solito metto la parentesi graffa {nella riga successiva.
Marco Demaio

2
Inoltre, fai attenzione se uno qualsiasi dei tuoi comandi annidati ha parentesi in (per esempio, qualcosa come "echo Something something (something else)" EDIT: ah, vedi la risposta di bk1e :)
Tim Barrass

31

SilverSkin e Anders hanno entrambi ragione. È possibile utilizzare le parentesi per eseguire più comandi. Tuttavia, devi assicurarti che i comandi stessi (ei loro parametri) non contengano parentesi. cmdcerca avidamente la prima parentesi chiusa, invece di gestire con garbo insiemi annidati di parentesi. Ciò potrebbe causare la mancata analisi del resto della riga di comando o il passaggio di alcune parentesi ai comandi (ad esempio DEL myfile.txt)).

Una soluzione alternativa è dividere il corpo del ciclo in una funzione separata. Nota che probabilmente dovrai saltare il corpo della funzione per evitare di "caderci dentro".

FOR /r %%X IN (*.txt) DO CALL :loopbody %%X
REM Don't "fall through" to :loopbody.
GOTO :EOF

:loopbody
ECHO %1
DEL %1
GOTO :EOF

3
Mentre siamo in argomento,% X non è mai corretto quando si tratta di nomi di file, usa sempre "% ~ X" (Nel tuo esempio qui, potresti cavartela usando% * nella sottofunzione probabilmente)
Anders

1
Questo è davvero un buon punto. Un buon esempio di un percorso che dimostra entrambi i problemi è C:\Program Files (x86).
bk1e
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.