Пакет Windows: вызвать более одной команды в цикле FOR?

124

Можно ли в командном файле Windows вызывать более одной команды в одном FOR цикле? Скажем, например, я хочу напечатать имя файла и после его удаления:

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

Я знаю, что в этом случае я мог бы решить эту проблему, выполнив два отдельных цикла FOR: один для отображения имени и один для удаления файла, но можно ли сделать это только в одном цикле?

Марко Демайо
источник

Ответы:

117
FOR /r %%X IN (*) DO (ECHO %%X & DEL %%X)
Мышечная
источник
2
На самом деле, я считаю, что скобки излишни. for %i in (1 2 3) do echo %i & echo fooпечатает то, что я ожидал: «1», «foo», «2», «foo», «3», «foo» (в отдельных строках).
bk1e
Разве это не должно быть &&лучше, чем &?
jww
9
@jww &&завершится ошибкой, если первая команда не удалась, &независимо от того , выполнит вторую команду.
yyny
Если это решение вызывает для вас синтаксическую ошибку, проверьте, есть ли у вас DOнеэкранированный парен между -parens. Вы можете избежать их, добавив ^к ним.
Константин Ван
199

Использование &подходит для коротких команд, но эта единственная строка может очень быстро стать очень длинной. Когда это произойдет, переключитесь на многострочный синтаксис.

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

Размещение (и )имеет значение. Круглые скобки после DOдолжны быть помещены в одну строку, иначе командный файл будет некорректным.

Подробнее if /?|find /V ""см.

Андерс
источник
12
Это решение выглядит чистым и читаемым. Я также хотел бы предупредить любого программиста, который использует это решение, что круглую скобку после DOсимвола НЕ следует помещать в следующую строку, иначе это приведет к остановке командного файла. В коде, когда я пишу цикл for, я обычно помещаю фигурную скобку в {следующую строку.
Марко Демайо,
2
Также - будьте осторожны, если в какой-либо из ваших вложенных команд есть скобки (например, что-то вроде «echo Something something (something else)» EDIT: а, см. Ответ bk1e :)
Тим Баррасс
31

СильверСкин и Андерс правы. Вы можете использовать круглые скобки для выполнения нескольких команд. Однако вы должны убедиться, что сами команды (и их параметры) не содержат скобок. cmdжадно ищет первую закрывающую скобку вместо того, чтобы изящно обрабатывать вложенные наборы скобок. Это может привести к тому, что остальная часть командной строки не будет проанализирована, или это может привести к тому, что некоторые из круглых скобок будут переданы командам (например DEL myfile.txt)).

Обходной путь - разделить тело цикла на отдельную функцию. Обратите внимание, что вам, вероятно, придется перепрыгивать через тело функции, чтобы не «проваливаться» в него.

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
источник
3
Пока мы обсуждаем эту тему,% X никогда не бывает правильным при работе с именами файлов, всегда используйте "% ~ X" (в вашем примере здесь вы могли бы избежать использования% * в подфункции, вероятно)
Андерс,
1
Это действительно хороший момент. Хорошим примером пути, демонстрирующего обе проблемы, является C:\Program Files (x86).
bk1e