Хочу поделиться восторгом.
Захотелось мне навести порядок в mp3 помойке. Использование библиотечных функций проигрывателей как то не очень прижилось - ибо тэги проставлены, мягко говоря, не совсем правильно. Да и записывать на носимые проигрыватели проще папками - по старинке.
Так вот. Для этого мне потребовались средства «малой автоматизации» - программка для формирования плэйлистов m3u из файлов по каталогам.
Нет чтобы, как все нормальные люди, взять perl и написать, я решил воспользоваться стандартными средствами Windows (в моем случае Vista).
Ибо перл я как то недолюбливаю за ненаглядность и бесконечность, а нормально рабочего борн шела под виндами найти нелегко.
Так же хочу заметить, что профессионально я не кодил никогда (т.е. написание программы никогда не было непосредственно оплачиваемой задачей, а только средством), поэтому, несомненно, найдётся множество людей с гораздо более крутыми историями (хотя их есть и у меня немало).
Остановлюсь на нескольких проблемах.
Батник называется, скажем, test.cmd. Мне надо передать аргументом каталог. В виндах название файла может содержать пробелы, поэтому возможны варианты:
test.cmd ДДТ
test.cmd "Несчастный Случай"
Как нетрудно догадаться, переменная %1 в батнике содержит «ДДТ» в первом и «"Несчастный Случай"» во втором случае.
Поскольку в итоге будет выполняться команда с модификатором, грубо говоря >>"%1.m3u", то кавычки нужно убрать.
Спасибо Висте, у команды set появился отличный модификатор убирания кавычек: %file:~1,-1%, что срезает первый и последний символ переменной %file%.
Пишем:
set f=%1
if `%f:~0,1%`==`"` set f=%f:~1,-1%
Получаем:
Непредвиденное появление: set.
С:\mp3>if `"`==`"` set f=Несчастный случай
После некоторых раздумий, сопровождающихся устными вспомогательными заклинаниями, я догадываюсь, что символ «"» не может экранироваться символом «'».
Решение, конечно, есть:
set f=%1
if `%f:~0,1%%f:~0,1%`==`""` set f=%f:~1,-1%
Дважды повторённые двойные кавычки становятся просто символом.
Отдельно хочу заметить, что set f=%1 - необходимо, поскольку переменная параметра батника %1 и переменная внутри батника %f% - совершенно по разному обрабатываются.
Ну хорошо. Переходим к следующему пункту программы - если параметра нет, то каталоги я как то и сам просканирую. Но при пустом %1 возникает ожжидаемая ошибка:
Непредвиденное появление: 1%f:~0.
С:\mp3>if `~0,1%f:~0,1f:~1,-1
Приходится писать второе условие:
set f=%1
if not '%1'=='' if `%f:~0,1%%f:~0,1%`==`""` set f=%f:~1,-1%
Результат предсказуем ;-)
Непредвиденное появление: 1%f:~0.
С:\mp3>if not ''=='' if `~0,1%f:~0,1f:~1,-1
В батнике строка интерпретируется вся сразу, даже введенные в Висте круглые скобки не помогают:
if not '%1'=='' (
if `%f:~0,1%%f:~0,1%`==`""` set f=%f:~1,-1%
)
поскольку они просто удлиняют интерпретируемую строку.
Решение тоже есть, только надо забыть не только об объектном, но и о структурном программировании (здравствуй Фортран!):
set f=%1
if '%1'=='' goto дальше
if `%f:~0,1%%f:~0,1%`==`""` set f=%f:~1,-1%
:дальше
Это работает.
Но остался один дополнительный штрих. Скажем, я хочу добавить «\» сзади переменной (это же каталог в конце концов ;-)
Пробую (пример несколько искусственный):
set f=%1
if `%f:~0,1%%f:~0,1%`==`""` (
set f=%f:~1,-1%
set f=%f%\
)
echo [%f%]
Результат:
test.cmd "Несчастный Случай"
["Несчастный Случай"\]
Объяснение простое - переменная меняется после окончания обработки всего оператора if. Ведь все, что в круглых скобках - это одна длинная такая строка.
В общем, пара часов потерянного времени - а столько морального удовольствия я давно не получал.
Теперь я с ещё большим моральным правом буду называть разработчиков виндов !@#!@$@#!$!!!!!
PS Я знаю по jscript, vbscript, perl, cygwin с sh и т.п. Мне просто хотелось поэкспериментировать со штатным средством виндов. Эксперимент удался ;-)