Секреты командной Строки Windows часть 2.

В продолжении темы Cmd – хаков, опишу еще несколько эффективных приемов работы с командной строкой.

>> Что такое enabledelayedexpansion?

Вообще я не хотел писать об этом, но т.к. в следующем примере это используется и в справке расписано туманно, напишу.

Обычно при использовании переменных в bat/cmd сценариях используется конструкция %переменная%, однако если значение переменной меняется в теле цикла и считывается там же, это может не работать. Например:

for %%i in (1,2,3) do (
    set "var=%%i"
    echo %var%
Rem Не выведет ничего
)

pause

Если запустить этот пример то интерпретатор просто 3 раза выполнит echo без каких то либо параметров. Для того чтобы все работало верно нужно использовать расширенный режим обработки команд. Задается он командой setlocal  с параметром enabledelayedexpansion, а выключается командой endlocal. Приведу пример:

setlocal enabledelayedexpansion

for %%i in (1,2,3) do (
    set "var=%%i"
    echo !var!
Rem Выведет 1,2,3
)

Pause

Теперь все выводится как и задумано. Замечу что переменная в данном случае обрамлена восклицательными знаками (!).

>> Создание динамических переменных в bat-файлах? Легко!

При написании сценариев командной строки, у администраторов, которые, хотя бы немного программировали на других языках программирования (а cmd можно отнести к ним с натяжкой) возникает определенный дискомфорт при обработке  больших массивов данных. Ведь в cmd отсутствуют массивы! Мы можем обойти это ограничение с использованием динамических переменных. Для этого воспользуемся расширенным режимом обработки команд.

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

Для начала создадим файл greeka.txt  с таким содержимым:

1.Ехал Грека через реку,Видит Грека - в реке рак.

2.Ехал Грека через реку,Видит Грека - в реке рак.

3.Ехал Грека через реку,Видит Грека - в реке рак.

4.Ехал Грека через реку,Видит Грека - в реке рак.

5.Ехал Грека через реку,Видит Грека - в реке рак.

6.Ехал Грека через реку,Видит Грека - в реке рак.

7.Ехал Грека через реку,Видит Грека - в реке рак.

8.Ехал Грека через реку,Видит Грека - в реке рак.

9.Ехал Грека через реку,Видит Грека - в реке рак.

10.Ехал Грека через реку,Видит Грека - в реке рак.

 

Далее, приступим к написанию нашего сценария:

    @echo off

    setlocal enabledelayedexpansion

Включаем режим расширенной обработки команд.

    set i=0

Объявляем вспомогательную переменную.

    for /F "tokens=*" %%a in (greka.txt) do (

Начало цикла  построчного перебора файла.

      set /A i=!i! + 1

Увеличиваем вспомогательный итератор на единицу. 

      set str!i!=%%a

Собственно сама незамысловатая конструкция создания динамических переменных, с именами str1, str2, str3 и так далее.

    )

Проверим как отработал наш сценарий.

Начало цикла 

Echo Это 10 строка... -------^>^> %str10%
Echo +++++++++++++++++++++++++++++++++++++++++++++
Echo +++++++++++++++++++++++++++++++++++++++++++++
Echo ...а  это вторая -------^>^> %str2%
pause

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

>> Поиск и замена текста в файлах средствами cmd/bat файла.

Многие администраторы и Power-пользователи линукс, при знакомстве с возможностями cmd, замечают такую досадную деталь, как отсутствие множества утилит для поиска и замены подстрок в  файлах.

Вообще под windows существует множество утилит для обработки строк в файлах, в том числе и портированных с #nix систем (тот же sed и supersed), но мы не ищем легких путей это будет не совсем чисто, т.к. в нужный момент этого всего может не оказаться под рукой.

Возможна ли реализация данной функции на cmd ? Конечно! А поможет нам в этом специальные строки расширения, а точнее конструкция  вида %переменная:A=B%, где переменная- переменная содержащая исходную подстроку, A – подстрока которую ищем, B – подстрока на которую меняем искомую подстроку в строке.

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

@echo off

setlocal enabledelayedexpansion

rem Собираем параметры командой строки переданной сценарию.
rem Например сценарий запущен "File_str_replace.bat greka.txt Грека Гитлер"
rem %1 = greka.txt %2=Грека %3=Гитлер
Set infile=%1
Set find=%2
Set replace=%3

    @echo off

    setlocal enabledelayedexpansion

    set COUNT=0

    for /F "tokens=* delims=," %%n in (!infile!) do (
    set LINE=%%n

    set TMPR=!LINE:%find%=%replace%!

REM Именно здесь происходит замена текущей строки!

    Echo !TMPR!>>TMP.TXT

REM Добавляем строку к временному файлу
                    )

REM Делаем резервное копирование исходного файла, на случай что что то пойдет не так…

copy %infile% %infile%.bak

REM Заменяем исходный файл временным

move TMP.TXT %infile%

Наш батник для поиска и замены подстрок файла готов. Теперь сгенерируем файл для него, да побольше! Сделаем это тоже батником:

@echo off
for /L %%i in (1,1,100000) do (

echo %%i.Ехал Грека через реку,Видит Грека - в реке рак.Сунул Грека в реку руку,Рак за руку Греку - цап!>>greka.txt
)

Получился файл, забитый поговоркой, размером ~ 10 мегабайт, неплохо для примера…  Запустим Наш сценарий введя в командной строке “File_str_replace.bat greka.txt Грека Гитлер” , для того чтобы заменить все слова Грека на Гитлер. Запустив увидим что через полторы минуты(неплохо для 20-ти летнего консольного мамонта) в нашем файле поговорка заменилась на “Ехал Гитлер через реку,Видит Гитлер - в реке рак.Сунул Гитлер в реку руку,Рак за руку Греку - цап”. Можно усовершенствовать сценарий, и даже прикрутить к ней регулярные выражения, но это уже мелкие технические детали :)

На сегодня пожалуй все, попозже продолжу.

Комментариев нет:

Отправить комментарий