Как обрабатывать несколько операторов 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 ответа

Решение
  1. Вы пропустили пробел перед каждым экземпляром символа ^.
  2. Вся ваша конструкция 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 токенов).

Другие вопросы по тегам