Решаем практические задачи на батниках

    Батники это не мощный язык программирования, но, в то же время, на нем можно решить много рутинных задач. Цель статьи не просто рассказать о возможностях Windows-консоли, а показать их, решая практические задачи с которыми мне приходилось сталкиваться.

    Подтверждение выполнения



    set answer=
    set /p answer="Выполнить? [y/n]:"
    if not "%answer%" == "y" exit /b


    Устанавливаем переменную answer в пустое значение (необходимо, для того чтобы затереть предыдущее значение, например, если батник исполняется несколько раз). set с ключом /p устанавливает значение переменной, которое вводится пользователем. Проверяем значение переменной и если оно не равно y завершаем выполнение батника.

    Как получить текущий месяц, день, год и т.п.?



    В батниках есть возможность получать подстроку используя синтаксис %variable:~m,n% Где variable это название переменной m – индекс первого символа, а n – количество символов подстроки.

    Следовательно, если команда echo %date% (а формат даты может у вас отличатся) выведет 13.06.2009, то для того чтобы получить текущий месяц достаточно выполнить %date:~3,2% Таким образом, если нам необходимо, например, сформировать имя файла или директории, которое соответствует текущему месяцу и дню, мы это сделаем так:

    set fname=%date:~3,2%%date:~0,2%


    Лично мне такое понадобилось для задания ключа /d для xcopy.

    Как вывести пустую строку в лог-файл?



    Я не сразу догадался, что это можно делать вот так: :)

    echo.>> %logfile%


    Т.е. нужно поставить точку после echo.

    Предыдущая команда выполнена успешно?



    В большинстве случаев это:

    if %errorlevel%==0 (
      echo OK>> %logfile%
    ) else (
      echo ERROR #%errorlevel% >> %logfile%
    )


    Архивирование файла с переменным именем



    for %%i in (c:\dir\#fe*.*) do rar a -ep c:\other_dir\%%~ni.rar %%i


    Задача состоит в том, чтобы заархивировать файл с именем, которое меняется ежедневно, но в другую папку. Следующим куском кода

    for %%i in (c:\dir\#fe*.*) do


    мы выбираем все файлы по маске, исполняя команду rar a -ep c:\other_dir\%%~ni.rar %%i для каждого, где %%~ni это только имя файла.

    Имя текущего исполняемого батника



    %~n0


    Нужно, например, для того чтобы вести один лог для нескольких батников.

    «Функция» в батниках



    Если мы исполняем в одном батнике несколько повторяющихся команд, но с разными значениями переменных, то это можно реализовать так:

    set thebat=c:\Program Files\The Bat!\thebat.exe
    set action=SEND
    
    set mailto=email_1@domain.com
    set subject=Subject_1
    set attach=c:\dir\file????
    call :mailit
    
    
    set mailto=email_2@domain.com
    set subject=Subject_2
    set attach=c:\dir\file*.rar
    call :mailit
    
    …
    
    exit
    
    :mailit
    @echo on
    "%thebat%" /MAILTO="%mailto%";SUBJECT="%subject%";ATTACH="%attach%";%action% >> %logfile%
    @echo off
    exit /b


    Таким образом, у меня отсылается десяток разных файлов разным получателям, используя The Bat! Такой файл читать и редактировать намного удобнее, чем это было бы десять команд The Bat! подряд.

    Получить последний по дате создание файл



    Для начала получим список всех файлов, отсортированных по дате модификации:

    dir /b /od /a-d c:\dir\file_*.xls


    И пройдемся по нему циклом.

    for /f "tokens=*" %%a in (' dir /b /od /a-d c:\dir\file_*.xls ') do set "lastfile=%%a"


    Логично, что по завершению цикла в переменной %lastfile% у нас будет последний по дате модификации файл ;)

    Выкачать файл по FTP



    ftp -s:file_to_ftp.txt 127.0.0.1


    Где файл file_to_ftp.txt будет у нас выглядеть следующим образом:

    login
    password
    bin 
    cd /files
    put file.xls 
    quit


    Создаем нумерованные каталоги с инкрементом на единицу



    set dir_last=
    for /f "tokens=*" %%i in ('dir /ad /b') do set dir_last=%%i
    
    if '%dir_last%'=='' (set dir_last=000)
    
    set dir_last=1%dir_last%
    set /a dir_last = %dir_last% - 1000
    set /a dir_new=%dir_last% + 1
    
    set dir_new=00%dir_new%
    set dir_new=%dir_new:~-3%
    md %dir_new%


    Разобраться в коде предлагаю вам самим. :) Основная возможность, которую я хотел показать данным примером, это использование ключа /a команды set для вычисления выражений. ;)
    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 29

      0
      огромное спасибо, давно хотел автоматизировать некоторые операции в винде!
        0
        Не за что. :) Рад, что пригодилось. :)
        0
        Занимательно, сам писáл батники для автоматизации сборок мидлетов, подобие анта.
        А вот для создания множества директорий с последовательными номерами использовал РНР, это IMHO проще, но только если локальный сервак крутится конечно.

        Вопрос такой, а возможно-ли написать батник для переименования директорий с середины изменив их имена на 1? К примеру если одна из папок удалена, а последовательность нарушать нельзя. Что скажите?
        Я тоже на РНР это делал в своё время, просто интересно
          0
          Для всяких переименований, имхо, удобнее тотал командер с его групповым переименованием.
            0
            Не могу не согласится. :)
            Есть также много специализированных утилит для этой задачи.
              0
              Не люблю ставить дополнтиельный софт ради тривиальных задач
                0
                Мне кажется в винде у многих тотал командер это не дополнительный, а основной софт :)
                  0
                  Согласен, я имел в виду это высказывание
                  > Есть также много специализированных утилит для этой задачи.
          • UFO just landed and posted this here
              0
              Не понял, что Вы имеете в виду?
              Вы против РНР? Или хотите сказать, что для подобной задачи есть более удобные варианты реализации?
              В любом случае, цель моего комента была просто рассказать об одном случае имeющем отношение к теме топика.
                –1
                P.S. Также попрошу обратить внимание на абревиатуру IMHO
                0
                Если я вас правильно понял, то это будет выглядеть приблизительно так:

                set counter=0
                
                for /f "tokens=*" %%i in ('dir /ad /b') do call :incren %%i
                
                
                :incren
                set /a counter=%counter%+1
                
                if not '%~1' == '' (
                  ren %~1 %counter%
                )
                exit /b
                
                  0
                  Если я правильно понял это код, то очень похоже. Вечером дома запущу, стало интересно. Спасибо
                  0
                  да нормально и PHP портабельный таскать: php.exe,php.ini, пара dll+нужные dll библиотеки.
                  Портабельно, функционал на 2, нет 3 порядка выше чем у батников…
                  +1
                  Полезно, только как-то не очень удобно. На python/perl и тп. поудобнее и поинтереснее. :)
                    +1
                    пайтон для таких задач это слишком круто. имхо, баш или перл.
                      +1
                      зато на питоне так приятно писать…
                      –1
                      В windows давно встроен wsh — скрипты пишутся на обычном javascript (или vb для любителей извращений) и работают на любой машине.
                        0
                        Да, сложные задачи на батниках решить или невозможно, или решение выглядит не совсем элегантно, но они всегда под рукой и замечательно решают много простых задач, как, например, архивирование нескольких файлов с заданными условиями.
                        +1
                        А кто будет потом разбирать эти ваши magical incantations?

                        Лучше возьмите нормальный ЯП с вменяемой семантикой и не морочьте себе голову.
                          –1
                          Ну, можно даже скомпилировать экзешку для особо сложных задач. :)
                          Возможностей батников мне пока хватало и разобраться в их особенностях (необходимых заклинаниях :) сложно только поначалу.
                          0
                          Полезная ссылка для тех, кому приходиться использовать батники: Frequently Asked Questions about Batch.
                            0
                            Все это хорошо, что написали такой пост, за это вам +. Только фактически ценная информация начинается с предпоследнего абзаца. Было здорово, если бы написали о всях покрытых тайной командах типа tasklist, как рубить процессы и т.д.
                              0
                              Спасибо! :) Я просто поделился решениями тех трудностей, с которыми мне приходилось сталкиваться, с надеждой, что они кому-нибудь пригодятся, даже если это будет только два последних абзаца. :)

                              С tasklist, к сожалению, мне не приходилось сталкиваться — не было необходимости. Если появится опыт — обязательно поделюсь.
                                0
                                taskkill /?
                              0
                              Кому не хватает BATCH, можете поставить Cygwin и писать на BASH :-)
                                0
                                >>>set fname=%date:~3,2%%date:~0,2%
                                Сразу облом: на 2000-м Windows данная конструкция ошибочна (т.к. там другой формат даты)

                                А батники как раз активно используются в корпоративном секторе (там где посерьезней) — системы бывают и W2K (XP-не аттестована) — а сторонний софт запрещен или разрешен в оч. небольшик количествах…
                                  0
                                  Процитирую себя :)

                                  Следовательно, если команда echo %date% (а формат даты может у вас отличатся) выведет 13.06.2009, то для того чтобы получить текущий месяц достаточно выполнить %date:~3,2%

                                Only users with full accounts can post comments. Log in, please.