Partia systemu Windows: wywołanie więcej niż jednego polecenia w pętli FOR?

124

Czy w pliku wsadowym systemu Windows można wywołać więcej niż jedno polecenie w jednej FOR pętli? Powiedzmy na przykład, że chcę wydrukować nazwę pliku i po usunięciu go:

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

Wiem, że w tym przypadku mógłbym to rozwiązać, wykonując dwie różne pętle FOR: jedną do wyświetlania nazwy, a drugą do usuwania pliku, ale czy można to zrobić tylko w jednej pętli?

Marco Demaio
źródło

Odpowiedzi:

117
FOR /r %%X IN (*) DO (ECHO %%X & DEL %%X)
SilverSkin
źródło
2
Właściwie myślę, że nawiasy są niepotrzebne. for %i in (1 2 3) do echo %i & echo foowypisuje to, czego bym się spodziewał: „1”, „foo”, „2”, „foo”, „3”, „foo” (w osobnych wierszach).
bk1e
Czy nie powinno być &&raczej niż &?
jww
9
@jww &&nie powiedzie się, jeśli pierwsze polecenie nie powiedzie się, &niezależnie wykona drugie polecenie.
yyny,
Jeśli to rozwiązanie powoduje błąd składni, sprawdź, czy między DOopcjami -parens znajduje się znak bez znaku zmiany znaczenia . Możesz im uciec, dodając ^do nich a.
Константин Ван
199

Używanie &jest dobre w przypadku krótkich poleceń, ale ta pojedyncza linia może bardzo szybko stać się bardzo długa. Kiedy tak się stanie, przełącz się na składnię wielowierszową.

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

Umieszczenie (i ma )znaczenie. Okrągłe nawiasy po DOmuszą być umieszczone w tym samym wierszu, w przeciwnym razie plik wsadowy będzie nieprawidłowy.

Zobacz if /?|find /V ""szczegóły.

Anders
źródło
12
To rozwiązanie wygląda na czyste i czytelne. Ostrzegłbym również programistę, który korzysta z tego rozwiązania, że ​​nawias okrągły po DOznaku NIE może być umieszczany w następnej linii, ponieważ spowoduje to przerwanie pliku wsadowego. W kodzie, kiedy piszę pętlę for, zwykle umieszczam nawias klamrowy w {następnej linii.
Marco Demaio,
2
Ponadto - bądź ostrożny, jeśli którekolwiek z twoich zagnieżdżonych poleceń ma nawiasy (na przykład coś takiego jak „echo Coś coś (coś innego)” EDYCJA: ah, zobacz odpowiedź bk1e :)
Tim Barrass
31

SilverSkin i Anders mają rację. Możesz użyć nawiasów, aby wykonać wiele poleceń. Musisz jednak upewnić się, że same polecenia (i ich parametry) nie zawierają nawiasów. cmdłapczywie wyszukuje pierwszy nawias zamykający, zamiast z wdziękiem obsługiwać zagnieżdżone zestawy nawiasów. Może to spowodować, że reszta wiersza poleceń nie zostanie przeanalizowana lub może spowodować, że niektóre nawiasy zostaną przekazane do poleceń (np DEL myfile.txt).).

Rozwiązaniem tego problemu jest podzielenie treści pętli na osobną funkcję. Zauważ, że prawdopodobnie będziesz musiał przeskoczyć wokół ciała funkcji, aby uniknąć „wpadnięcia” do niego.

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
bk1e
źródło
3
Skoro już o tym mowa,% X nigdy nie jest poprawne, gdy mamy do czynienia z nazwami plików, zawsze używaj „% ~ X” (w twoim przykładzie prawdopodobnie możesz uciec z użyciem% * w podfunkcji)
Anders,
1
To naprawdę dobra uwaga. Dobrym przykładem ścieżki, która pokazuje oba problemy, jest C:\Program Files (x86).
bk1e