Для хардкорных программистов

Sep 12, 2009 11:22

Хочу поделиться восторгом.

Захотелось мне навести порядок в 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 и т.п. Мне просто хотелось поэкспериментировать со штатным средством виндов. Эксперимент удался ;-)
Previous post Next post
Up