Как обрабатывать несколько операторов for в командном файле?
Я пытаюсь создать пакетный файл, который будет принимать список пользователей из текстового файла, выполнять запрос dsquery для Active Directory, чтобы определить, была ли учетная запись отключена, и затем выводить результаты в другой текстовый файл, содержащий пользователя. Идентификатор и статус (да / нет) того, были ли они отключены или нет.
Мне кажется, что я неправильно позиционирую кавычки или круглые скобки, но я также не уверен на 100%, могут ли множественные операторы for быть вложенными, как это. Вклад очень ценится.
for /f "tokens=1" %%G in (termlist.txt) do (
for /f "Tokens=*" %%a in ('dsquery user -samid %%G^|dsget user -disabled^| Find /v "disabled"^| Find /v "dsget succeeded"') do set disable=%%a)
echo "%%G %disable%" >> termvalid.txt)
3 ответа
- Вы пропустили пробел перед каждым экземпляром символа ^.
- Вся ваша конструкция FOR загружается одной строкой (независимо от того, сколько физических строк она занимает)... поэтому% disable% раскрывается во время загрузки всей конструкции и не изменяется во время выполнения. Вы можете включить отложенное расширение, но в этом нет необходимости.
Попробуйте это (используйте первую строку, если хотите убедиться, что вы не добавляете старый нежелательный файл):
if exist termvalid.txt del /f /q termvalid.txt
for /f "tokens=1" %%G in (termlist.txt) do (
for /f "Tokens=*" %%a in ('dsquery user -samid %%G ^|dsget user -disabled ^| Find /v "disabled" ^| Find /v "dsget succeeded"') do echo "%%G %%a" >> termvalid.txt))
Существует простой способ проверить, что несколько вложенных команд имеют правильное количество круглых скобок. Просто сделайте отступ каждой вложенной команды на три пробела вправо, поместите открывающие левые скобки в одну строку и поместите закрывающие правые скобки в тот же столбец команды, которую она закрывает. Например
for %%a in (set) do (
for %%b in (set) do (
if %%a equ %%b (
then part
) else (
else part
)
)
)
Когда я применяю такой формат к вашему коду, я получаю это:
for /f "tokens=1" %%G in (termlist.txt) do (
for /f "Tokens=*" %%a in ('dsquery user -samid %%G^|dsget user -disabled^| Find /v "disabled"^| Find /v "dsget succeeded"') do set disable=%%a
)
echo "%%G %disable%" >> termvalid.txt)
Таким образом, теперь очевидно, что есть дополнительные правые скобки (которые игнорируются), но что %%G находится вне своего FOR. Есть два способа решить эту проблему; устраняя правильные парентезы и перемещая ECHO в нужное место:
for /f "tokens=1" %%G in (termlist.txt) do (
for /f "Tokens=*" %%a in ('dsquery user -samid %%G^|dsget user -disabled^| Find /v "disabled"^| Find /v "dsget succeeded"') do set disable=%%a
echo "%%G !disable!" >> termvalid.txt
)
... или вставьте пропущенные левые скобки:
for /f "tokens=1" %%G in (termlist.txt) do (
for /f "Tokens=*" %%a in ('dsquery user -samid %%G^|dsget user -disabled^| Find /v "disabled"^| Find /v "dsget succeeded"') do (
set disable=%%a
)
echo "%%G !disable!" >> termvalid.txt
)
... кроме проблемы доступа к%disable% через задержанную переменную! расширение, потому что оно находится внутри команды FOR.
Вложенные for
петли совершенно действительны. Однако вы должны убедиться, что ни одна из переменных токена не будет перекрываться.
for /f "tokens=1,2" %%A in ("hello world") do echo %%A
использует %%A и %%B (из-за tokens=1,2
), хотя только %%A объявлено и используется явно, поэтому следующая безопасная переменная для использования - это %%C. Тем не менее, переменные чувствительны к регистру, поэтому вы можете использовать от %%A до %%Z и от %% a до %%z, что означает, что то, как у вас есть это в вашем коде, будет работать нормально (и это также будет работать нормально, если вы использовали %%A, если внутренний цикл for не создал более 6 токенов).