В прошлом номере в статье «Возможности команды For» я начал разговор об одном из «невоспетых героев» Windows — команде For. Я рассказал о том, как благодаря For программа получает возможность обрабатывать символы шаблонов, даже если она их не понимает. Например, чтобы заставить воображаемую команду Processfile обрабатывать каждый файл, чье имя начинается с «z», можно воспользоваться комбинацией

for %a in (z*) do processfile %a

Другими словами, For превращает программу, обрабатывающую один файл единовременно, в программу, способную работать с последовательностью файлов, — очень удобное свойство. Однако в прошлый раз мне удалось описать лишь самые простые возможности For. Перейдем к более сложным.

Несколько лет назад появилась информация о забавном сбое в разделе Active Directory Users and Computers в версиях консоли управления (MMC) Windows Server 2003 и Windows 2000 Server. Откройте раздел, выберите любую группу, щелкните правой клавишей мыши на ее имени и выберите Properties. В открывшемся диалоговом окне свойств вы увидите вкладку Members, где перечислены все члены группы — каждый со значком в виде головы. Если в группе более 500 членов, головы из черноволосых становятся седыми. Естественно, узнав об этом дефекте, я хотел лично в нем убедиться. Но как создать 501 учетную запись?

Известно, что учетную запись в домене можно создавать из командной строки при помощи команды

net user <имя пользователя> <пароль> /add /domain

Однако перспектива выполнить команду Net User 501 раз выглядит не слишком заманчивой. Ключ /l, предписывающий For вести счет повторений, позволяет в одной строке задать выполнение команды Net User 501 раз. Синтаксис конструкции For /l следующий:

for /l %a in (<первый номер> <шаг> <последний номер>)
do <команда>

Например, результатом команды

for /l %a in (1 1 5) do echo %a

является последовательный возврат номеров от 1 до 5. Таким образом, можно набрать комбинацию

for /l %a in (1 1 501)
do net user testuser%a
ComplexPassword$ /domain /add

Эта команда позволяет создать 501 учетную запись с именами testuser1, testuser2, … testuser501. Все пользователи имеют одинаковый пароль — ComplexPassword$, а учетные записи создаются в указанном домене. Рекомендую поупражняться с экспериментальным доменом. После выполнения команды следует открыть раздел Active Directory Users and Computers, найти группу Domain Users и исследовать ее состав. Вы убедитесь, что все пиктограммы «поседели».

Избавиться от созданных учетных записей позволяет команда

net user <имя пользователя> /delete /domain

Однако не забудьте усилить ее при помощи For, чтобы удалить сразу все учетные записи, как показано ниже:

for /l %a in (1 1 501) do net user testuser%a /domain /delete

Составной вариант

До сих пор сегмент для указания выполняемого действия у For был представлен единичной командой (в частности, в прошлом месяце — Chml, на этот раз — Net User). А что если выполнить несколько заданий одной командой For?

Для примера предположим, что требуется не только создать пользователя по имени testuserномер, но также добавить его в локальную группу домена под названием test. Прежде всего, добавить пользователя в локальную группу домена позволяет команда

net localgroup <имя группы> <имя пользователя> /add

Чтобы при помощи For одновременно добавить пользователя в группу test, можно поместить две команды в одну строку, разделив их символом & и заключив в скобки. Тогда для создания 501 пользователя и добавления каждого из них в группу test можно воспользоваться следующей командой:

for /l %a in (1 1 501)
do (net user testuser%a
ComplexPassword$ /domain /add
& net localgroup test testuser%a /add)

Теперь обсудим, как с помощью конструкции For /f можно задать применение конкретной команды к заданному списку файлов.

For для файлов

С этой возможностью команды For я познакомился несколько недель назад, анализируя результаты фотосъемки. Накануне я сделал множество снимков белой американской цапли крупным планом. Получилось некоторое количество хороших детальных фотографий среди подавляющего большинства менее удачных. Я решил записать все снимки на DVD, а самые лучшие сохранить на жестком диске.

Может показаться, что отделить несколько снимков несложно — например, открыть весь список снимков в одном окне и перетащить самые удачные в другую папку. Однако значительную часть экрана я был вынужден отвести под просмотр изображений и у меня не хватало места для размещения двух окон Windows Explorer. Однако свободного пространства хватило для небольшого окна блокнота Notepad, где я ввел имена выбранных для сохранения файлов, оставляя простор для системы просмотра изображений.

У меня была заполненная файлами папка C: ewpics и созданный текстовый файл keepers.txt со списком снимков, которые требовалось скопировать в папку C:goodpics. Я решил последовательно извлекать каждую строку из keepers.txt и использовать ее как имя файла для копирования в C:goodpics. Как решить эту задачу из командной строки Windows?

Решив воспользоваться командой For, я углубился в недра оперативной подсказки, напомнившей мне о ключе /f. Получилась следующая команда:

for /f %i in (C: ewpicskeepers.txt)
do copy C: ewpics\%i C:goodpics

Для пояснения рассмотрим упрощенный синтаксис конструкции For /f:

for /f <переменная>
in (<имя файла со списком желаемых объектов>)
do <операция над переменной>

Например, чтобы с помощью конструкции For /f просто отобразить на экране выбранные для копирования файлы, можно использовать следующую комбинацию:

for /f %i in (C: ewpicskeepers.txt) do echo %i

Конструкция For /f разбирает содержимое файла keepers.txt, последовательно извлекая по одной строке и помещая ее содержимое на занимаемое переменной место в памяти, которое я назвал «%i» (здесь подходит любое имя, которому предшествует символ процента). Затем For /f выполняет любое действие, указанное в правой части команды, заменяя оба символа комбинации «%i» фактическим значением, извлеченным For из файла keepers.txt последним.

Таким образом, если первой строкой сделать pic1.cr2, а второй и последней — pic7.cr2, то For /f сначала выполнит возврат значения pic1.cr2, вынуждая Windows отобразить pic1.cr2 в окне командной строки, а затем выведет pic7.cr2 в этом окне и остановится.

Но это еще не все возможности конструкции For /f. Вместо указания файла в скобках можно поместить туда произвольную команду в окружении одиночных кавычек. Тогда For будет выполнять эту команду и использовать очередной выходной результат ее деятельности в качестве строки текста, над которой выполняется операция, как если бы эта операция применялась к строкам файла keepers.txt.

For также допускает использование более одного файла в качестве входных данных в скобках, например если в первом случае, помимо файла keepers.txt, требуется указать и файл под другим именем — keepers2.txt:

for /f %i
in (C: ewpicskeepers.txt C: ewpicskeepers2.txt)
do copy C: ewpics\%i C:goodpics

Прочие возможности For

Безусловно, For обладает и другими возможностями. Однако я надеюсь, что мой рассказ об этом оригинальном инструменте Windows послужит читателям отправным пунктом для самостоятельных экспериментов с ним. Если в новом году вы освоите лишь один новый инструмент, запускаемый из командной строки, пусть это будет команда For!


Марк Минаси - редактор Windows IT Pro, MCSE и автор книги Mastering Windows Server 2003 (издательство Sybex). mark@minasi.com