Главная > Без вредных советов, Уголок гика > Работа со строками в командных файлах Windows 7

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

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

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

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


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

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

set mytime=%time::=_%

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

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

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

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

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

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

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

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

echo %var: =%

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

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

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

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

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

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

echo %var1:%var%=%

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

call echo %var1:%var%=%

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

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

call echo %%var1:%var%=%%

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


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

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

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

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

Или

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

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

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


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

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

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

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

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

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

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

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


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

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

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

    После rem - пробел, это важно(rem /?)

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


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

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

http://ss64.com/nt/

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

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

 

Winreview.ru можно найти в Вконтакте, Facebook и Twitter. Присоединяйтесь!

Комментарии

  1. Vadim Sterkin

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

  2. Сергей Ткаченко

    Теперь только в следующем году -)

  3. rsuan

    Спасибо за статью!

  4. Angel of Despair

    А все ведь из-за репаков NFS, да? )

  5. Сергей Ткаченко

    Да.

  6. Echinosor

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

  7. Nikita

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

  8. paulroot

    я прозрел...

    еще бы была в винде команда замены в текстовом файле (типа команды поиска find findstr только еще с заменой)

    Спасибо за статью и особенно за котика, его я посмотрел в первую очередь!

  9. Mopuapmu

    @paulroot
    Воспользуйтесь gsar из GnuWin32

    gsar.exe -s"SomeString" -r"AnotherString" -o file.dat

    https//ru.wikipedia.org/wiki/GnuWin32

    http//gnuwin32.sourceforge.net

  10. Сергей Ткаченко

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

  11. Артем

    Спасибо. Как раз то, что искал.

  12. Антон

    Очень познавательная статья. Спасибо.

    Только, увы, и в ней нет информации как заменить/удалить в переменной символ звездочка (*)

    Например хочу из Test*Test получить Test_Test

    Конструкция

    set a=Test*Test

    set a=%a*=_%

    echo %a%

    не работает

    Также не работает конструкция

    set a=Test*Test

    call echo %a*=_%

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

  13. ччч

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

  14. Сергей Ткаченко

    @ччч
    А если переведёт как Power Sink? )

    Писали бы PowerShell, хотя перевод да, отличный.

  15. Антон

    @Сергей Ткаченко
    Ха-ха, такого перевода еще не слышал, и действительно не понял о чем идет речь.

    Но теперь так и придется изучать и использовать PowerShell, т.к. средствами командного процессора такое решить не получается.

    Спасибо за подсказки.

Написать комментарий