В прошлом номере в статье «Возможности команды 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