Работа со строками в командных файлах Windows 7

Работа со строками в командной строкеПозавчера мне пришлось написать простенький командный файл, бекапящий профиль приложения. В качестве имени папки с резервной копией мне возжелалось использовать переменные окружения %date% и %time%. Если вы проходили в институте начальный курс информатики, вы должны знать, что %time%  в этом случае является ничем иным, как граблями, остро торчащими на пути, так значение содержит недопустимый символ ":". Я никогда не занимался разбором строк в командных файлах, и случай как нельзя лучше подходил для того, чтобы прокачать свои скилы.

Я хочу поделиться с вами своими изысканиями, и анонсирую скучную, унылую техническую статью. Дочитавшему до конца - покажу котика.
В современных ОС интерпретатор командной строки позволяет выполнять простейшие строковые операции:

Замена символов/подстроки в переменной командной строки


Это то, что мне было нужно в первую очередь. Напомню, моя задача в первую очередь избавиться от двоеточий.

Решается очень просто:

[code]set mytime=%time::=_%[/code]

В этом примере используется синтаксис вида:

[code]%Переменная:ЧтоНайти=НаЧтоЗаменить%[/code]

В моем случае заменяется двоеточие на символ нижнего подчеркивания, и результат выглядит так:

замена символа в строке (cmd.exe)

Само собой, можно заменять не отдельные символы, а целые словосочетания:

Замена строки в переменной cmd.exe

Как ещё можно воспользоваться функцией замены? Например:

Удалить все пробелы из значения переменной

[code]echo %var: =%[/code]

Удалить пробелы из переменной cmd.exe

Замена какой-либо части строки

Вы можете использовать символ "*" для определения того, что обработке подлежит часть строки, предшествующая указанному выражением. Я не знаю, как написать это по-человечески, вот что я имею ввиду:

К сожалению, "звёздочкой" нельзя указать, что отсечь надо часть строки после указанного выражения. Эта задача решается в два этапа:

  1. в отдельную переменную помещается строка, из которой удалено всё, что находится до ключевого выражения. Т.е. в ней остается "хвост", искомое выражение плюс всё, что после него.
  2. затем из оригинальной переменной удаляется значение переменной, полученной на первом шаге. Здесь потребуется вызов команды СALL:

Инструкция CALL необходима для разворачивания значения переменной, подлежащей замене. Без неё интерпретатор отработает неверно, и вот эта конструкция не сработает:

[code]echo %var1:%var%=%[/code]

Необходимо писать:

[code]call echo %var1:%var%=%[/code]

Не забывайте, что при использовании таких конструкций в командных файлах знаки процентов должны быть удвоены:

[code]rem Работаем внутри командного файла

call echo %%var1:%var%=%%[/code]

Поиск подстроки


Используя опыт, полученный выше, можно написать простейшую проверку вида "содержит/не содержит".

Например, вот так:

[code]set var1=Мама мыла раму
set var2=%var1:Мама=%

if NOT "%var1%" == "%var2%" (echo Подстрока найдена)[/code]

Или

[code]set var1=Мама мыла раму
set var2=%var1:Мама=%

if NOT "%var1%" == "%var2%" (echo Подстрока найдена)  else  (echo Подстрока не найдена) [/code]

Выделение подстроки из переменной


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

[code]set var2=%var1:~начальная_позиция%
set var2=%var1:~начальная_позиция,-отбросить_символов_с_конца_строки%
set var2=%var1:~начальная_позиция,длина%[/code]

Синтаксис очень простой, поэтому сразу перейдем к примерам.

Выделение подстроки с начиная определенной позиции

Выделение части строки, например, "середины"

Выделение определенного количества символов

Начальная позиции строки  - нулевая.

Работа с наборами "ключ - значение"


Здесь, в общем-то, тоже никакой магии нет. В основе разбора лежит всё та же рассмотренная выше замена подстроки на пустое значение.

Алгоритм действий такой:

  • Создается переменная, содежащая в себе значения вида <ключ><разделитель значения><значение><разделитель пары>. Назовем её условно "словарь".
  • В переменную, которая будет содержать значение, записывается всё, что следует после ключа. По аналоги с заменой части строки, нужно использовать звездочку перед выражением <ключ><разделитель значения>.
  • Полученный результат нужно "почистить", так как он может содержать в себе остаток словаря. Для этого прибегнем к хитрости и выполним составную команду.
    Предположим, мы в качестве разделителя пары словаря используем точку с запятой. Тогда мы сможем довольно изящно "убить" оставшуюся часть словаря, поместив его в комментарии командой rem.
    [code]set value=%value:;=&rem %[/code]
    После rem - пробел, это важно(rem /?)

Теперь практический пример:


Я надеюсь, эта информация оказалась для вас полезной и сэкономит вам время, если у вас появится задача обработки строк. Впрочем, тему я раскрыл не полностью, и если у вас есть какие-то дельные личные наработки и приёмы обработки строк в командном интерпретаторе Windows, я совсем не против увидеть их в комментариях.

Материалы по теме:

http://ss64.com/nt/

Форум о скриптах на OSZone - рекомендую.

Спасибо, что дочитали до конца.

 

Работа со строками в командных файлах Windows 7: 15 комментариев

  1. Полезные приемы, спасибо. Не совсем понял заключительную часть о наборах «ключ — значение». С учетом того, что материал рассчитан на начинающих скриптовиков, можно было объяснить назначение фичи получше. Пример это не слишком раскрывает…

  2. Теперь только в следующем году 🙂

  3. Вспоминается из башорга: «начальник заходит, а я увлеченно лопаю попкорн и смотрю в монитор. он подходит, смотрит в моник, а там мануал по настройке анализатора логов для прокси» (комментарий навеян котиками). А за статью — спасибо.

  4. Спасибо за интересную статью. Только заключительная часть о наборах «ключ — значение» какая-то неполная.

  5. я прозрел…
    еще бы была в винде команда замены в текстовом файле (типа команды поиска find findstr только еще с заменой)
    Спасибо за статью и особенно за котика, его я посмотрел в первую очередь!

      1. Да в GnuWin32 чего только нет. Если уж рассматривать этот порт, можно воспользоваться массой других утилит тоже.

  6. Очень познавательная статья. Спасибо.
    Только, увы, и в ней нет информации как заменить/удалить в переменной символ звездочка (*)
    Например хочу из Test*Test получить Test_Test
    Конструкция
    set a=Test*Test
    set a=%a:*=_%
    echo %a%
    не работает
    Также не работает конструкция
    set a=Test*Test
    call echo %a:*=_%

    Может кто поможет в решении данного вопроса?

    1. Антон, юзай «раковину власти» (с) гугл-переводчик , там с переменными можно разные непотребства сотворить средствами батника можно исключительно богоугодные процедуры совершать.

      1. А если переведёт как Power Sink? 🙂
        Писали бы PowerShell, хотя перевод да, отличный.

        1. Ха-ха, такого перевода еще не слышал, и действительно не понял о чем идет речь.
          Но теперь так и придется изучать и использовать PowerShell, т.к. средствами командного процессора такое решить не получается.
          Спасибо за подсказки.

Обсуждение закрыто.