3 / 3 / 0
Регистрация: 31.10.2013
Сообщений: 25
|
|
1 | |
for /f "delims=" %%b in ('dir !DirName! /b /s /a-d') do () жрёт символы "!" и "^"31.10.2013, 22:01. Показов 14472. Ответов 27
Метки нет (Все метки)
Добрый день, коллеги.
День сегодня убил, но так и не понял что делать, может поможете добрым советом. Кусок батничка: Код
@ECHO OFF SETLOCAL EnableExtensions EnableDelayedExpansion SET DirName=!CD! IF EXIST 1.txt DEL 1.txt FOR /F "DELIMS=" %%B IN ('DIR !DirName! /B /S /A-D') DO ( ECHO %%B>>1.txt ) Всё хорошо и просто, но. Если путь к файлу содержит символы "!"или "^", то они теряются. От "SETLOCAL EnableExtensions EnableDelayedExpansion" отказаться не могу, у меня внутри цикла FOR есть ещё и счётчик. Поэтому и гимор с "!". Что делать?
0
|
31.10.2013, 22:01 | |
Ответы с готовыми решениями:
27
Dirname(dirname(__FILE__) Добавить в delims критерий пробела Dirname(__FILE__) функция scan($dir) не может распознать символы из диапозона utf8mb4 в названиях файлов |
1779 / 761 / 130
Регистрация: 09.04.2011
Сообщений: 1,325
|
||||||
31.10.2013, 22:44 | 2 | |||||
E30M20B20, а если так?
1
|
3 / 3 / 0
Регистрация: 31.10.2013
Сообщений: 25
|
|
31.10.2013, 23:16 [ТС] | 3 |
Так символы не ест, но не работает счётчик. Мой батник чуть подробнее:
Код
@ECHO OFF SETLOCAL EnableExtensions EnableDelayedExpansion SET DirName=!CD! SET /A N=0 IF EXIST 1.txt DEL 1.txt FOR /F "DELIMS=" %%B IN ('DIR !DirName! /B /S /A-D') DO ( SET /A N+=1 IF /I "!N!"=="1" (ECHO MPCPLAYLIST>1.txt) ECHO !N!,type,^0>>1.txt ECHO !N!,filename,%%B>>1.txt )
0
|
Модератор
5197 / 2079 / 406
Регистрация: 06.01.2013
Сообщений: 4,793
|
||||||
31.10.2013, 23:45 | 4 | |||||
Вынести вывод в отдельную процедуру, в которой будет setlocal disabledelayedexpansion, а в конце endlocal
Добавлено через 1 минуту Хотя нет, вынести не получится, придется прямо в цикле
0
|
1779 / 761 / 130
Регистрация: 09.04.2011
Сообщений: 1,325
|
||||||
31.10.2013, 23:46 | 5 | |||||
Не по теме: E30M20B20, наверное не стоит искусственно создавать сложности для батников, используя в именах директорий и файлов спецсимволы. Постарайтесь от их избавиться вручную. Если вам нужно "поднять" директории вверх, попробуйте использовать например нижний подчерк "_folder1 " поясните строчку 11 кода
0
|
3 / 3 / 0
Регистрация: 31.10.2013
Сообщений: 25
|
|
01.11.2013, 00:06 [ТС] | 6 |
sov44, это такой формат плейлиста от MediaPlayerClassic
Код
MPCPLAYLIST 1,type,0 1,filename,D:\3\01. Paul Mauriat - El Bimbo.mp3 2,type,0 2,filename,D:\3\04-Neghivaya_voda.alac FraidZZ, Но как вытащить наружу счётчик? Код
@ECHO OFF SETLOCAL EnableExtensions EnableDelayedExpansion SET DirName=!CD! SET /A N=0 IF EXIST 1.txt DEL 1.txt FOR /F "DELIMS=" %%B IN ('DIR !DirName! /B /S /A-D') DO ( SET /A N+=1 IF /I "!N!"=="1" (ECHO MPCPLAYLIST>1.txt) ECHO !N!,type,^0>>1.txt setlocal disabledelayedexpansion ECHO !N!,filename,%%B>>1.txt endlocal ) А создавалка плейлистов должна всё это переваривать.
0
|
Модератор
5197 / 2079 / 406
Регистрация: 06.01.2013
Сообщений: 4,793
|
|||||||||||
01.11.2013, 00:18 | 7 | ||||||||||
В цикле:
23 тысячи файлов лучше через VBS перелопатьте. Я как просплюсь код сюда скину, надеюсь оффтопом не будет. А пока просто объемный код мозГ создавать не в состоянии
1
|
3 / 3 / 0
Регистрация: 31.10.2013
Сообщений: 25
|
|
01.11.2013, 00:52 [ТС] | 8 |
FraidZZ, О, заработало! (первый вариант, второй не пробовал) Спасибо огромное!
Да ладно, написал уже на batе, роднее оно как-то, ближе, чем vbs... Добавлено через 33 минуты Второй вариант тоже работает. Но всё равно это не годится. Дело в том, что снаружи этого FOR есть ещё один FOR, и если сделать setlocal disabledelayedexpansion endlocal, то там тоже ломаются переменные. Как бы так обойтись без setlocal disabledelayedexpansion?
0
|
Dragokas
|
01.11.2013, 05:51
#9
|
Не по теме: sov44, экранирование 0-потока, чтобы представить 0 как строку а не служебную команду,
1
|
Модератор
5197 / 2079 / 406
Регистрация: 06.01.2013
Сообщений: 4,793
|
|
01.11.2013, 13:43 | 10 |
Никак. Без этого сожрет знаки !
Плюс ко всему, VBS быстрее в сотни раз. Честно. На 23 тысячи файлов это очень актуально. Добавлено через 2 минуты Хотя, приведите весь батник, посмотрим, что можно сделать
0
|
3 / 3 / 0
Регистрация: 31.10.2013
Сообщений: 25
|
|
01.11.2013, 15:09 [ТС] | 11 |
Нет, ну я ещё не сдаюсь. Добью батник (или он меня), возьмусь за вбсник.
Переписал я всё заново вообще без setlocal disabledelayedexpansion. Очередные вопросы: 1. Как заставить конструкцию FOR /F "DELIMS=" %%A IN ('DIR %BaseDir% /B /S /AD') DO () выдавать не только имена всех каталогов ниже, но и плюс к ним имя самого каталога %BaseDir%? Или, если это невозможно, как снаружи цикла FOR вручную присвоить переменной %%A значение %BaseDir%? 2. Как организовать счётчик внутри цикла FOR не прибегая к setlocal enabledelayedexpansion?
0
|
Модератор
5197 / 2079 / 406
Регистрация: 06.01.2013
Сообщений: 4,793
|
|||||||||||
01.11.2013, 15:34 | 12 | ||||||||||
Вот вам аналогичный сканер на VBS, все как обещал
Через %%N%% попробуйте Добавлено через 2 минуты Вернее не просто %%N%%, а так
1
|
3 / 3 / 0
Регистрация: 31.10.2013
Сообщений: 25
|
|
01.11.2013, 15:59 [ТС] | 13 |
FraidZZ,
По первому своему вопросу разобрался - чтобы выводилась и текущая директория тоже, надо так: FOR /F "DELIMS=" %%A IN ('DIR %BaseDir%* %BaseDir% /B /S /AD') DO () VBS не смотрел. Допишу BAT - возьмусь.
0
|
Модератор
5197 / 2079 / 406
Регистрация: 06.01.2013
Сообщений: 4,793
|
||||||
01.11.2013, 16:21 | 14 | |||||
Можно вынести цикл в отдельную процедуру
1
|
3 / 3 / 0
Регистрация: 31.10.2013
Сообщений: 25
|
|
01.11.2013, 20:01 [ТС] | 15 |
0
|
Модератор
5197 / 2079 / 406
Регистрация: 06.01.2013
Сообщений: 4,793
|
|
01.11.2013, 20:40 | 16 |
Крышечки не передадите. Только VBS
0
|
3 / 3 / 0
Регистрация: 31.10.2013
Сообщений: 25
|
|
01.11.2013, 21:45 [ТС] | 17 |
Крышечки - это вообще тяжёлый случай.
Так. А если никуда данные не передавать, а передавать в парсер счётчик, там его проверять, и возвращать exit code? Но опять же непонятно что с ним дальше делать. Код
FOR /F "DELIMS=" %%A IN ('DIR %BaseDir%* %BaseDir% /B /S /AD') DO ( CALL :Parse IF ERRORLEVEL 1 (ECHO "бубубу">file.txt) ) EXIT :Parse IF /I "%N%"=="1" (EXIT /B 1) EXIT /B 0 Добавлено через 12 минут Гагага, я угадал! Всё, так всё работает! Добавлено через 5 минут Вот полный листинг. Всё проверено - работает. Но действительно очень медленно. Особенно там, где проверяется таблица расширений. Конструктивно покритикуйте пжлст. Код
@ECHO OFF SET BaseDir=D:\3 rem SET BaseDir=\\IOMEGA-2TB\MUSICMP3 SET STARTTIME=%TIME:~,8% IF "%STARTTIME:~,1%"==" " (SET STARTTIME=0%STARTTIME:~-7%) SET STARTDATETIME=%DATE% %STARTTIME% SET TIME1=%TIME:~,8% IF "%TIME1:~,1%"==" " (SET TIME1=0%TIME1:~-7%) CLS & ECHO. & ECHO Создавалка плейлистов .mpcpl для Media Player Classic - Home Cinema ECHO. & ECHO Базовый каталог - %BaseDir% ECHO. & ECHO %TIME1% Убиваю существующие плейлисты... REM Повторяем для всех директорий включая текущую и вложенные FOR /F "DELIMS=" %%B IN ('DIR %BaseDir%* %BaseDir% /B /S /AD') DO ( FOR /F %%I IN ("%%B") DO ( IF EXIST %%B\%%~nI.mpcpl (DEL %%B\%%~nI.mpcpl) ) ) SET TIME2=%TIME:~,8% IF "%TIME2:~,1%"==" " (SET TIME2=0%TIME2:~-7%) CLS & ECHO. & ECHO Создавалка плейлистов .mpcpl для Media Player Classic - Home Cinema ECHO. & ECHO Базовый каталог - %BaseDir% ECHO. & ECHO %TIME1% - %TIME2% Старые плейлисты убил. ECHO %TIME2% Создаю новые плейлисты... REM Повторяем для всех директорий включая текущую и вложенные FOR /F "DELIMS=" %%A IN ('DIR %BaseDir%* %BaseDir% /B /S /AD') DO ( SET /A N=0 REM Если текущая директория пустая, не делаем DIR %%A /B /S /A-D 2>NUL >NUL && ( REM Повторяем для всех файлов во всех директориях включая вложенные FOR /F "DELIMS=" %%B IN ('DIR "%%A" /B /S /A-D') DO ( REM Проверяем, есть ли расширение файла в списке FOR /F %%C IN ("%%B") DO ( FOR %%D IN (.ac3, .dts, .aif, .aifc, .aiff, .alac, .amr, .ape, .apl, .au, .snd, .cda, .flac, .m4a, .m4b, .m4r, .aac, .mid, .midi, .rmi, .mka, .mp3, .mpa, .mp2, .m1a, .m2a, .mpc, .ofr, .ofs, .ogg, oga, .opus, .ra, .tak, .tta, .wav, .wma, .wv, .aob, .mlp) DO ( IF "%%~xC"=="%%D" ( REM Создаём запись в плейлисте CALL SET /A N=%%N%%+1 CALL :111 IF ERRORLEVEL 1 (ECHO MPCPLAYLIST>%%A\%%~nA.mpcpl) CALL ECHO.%%N%%,type,^0>>%%A\%%~nA.mpcpl CALL ECHO.%%N%%,filename,%%B >>%%A\%%~nA.mpcpl ) ) ) ) REM Если плейлист создался, конвертируем его в CP1251 IF EXIST %%A\%%~nA.mpcpl (fdoswin.exe /OFF %%A\%%~nA.mpcpl %%A\%%~nA.mpcpl >NUL) ) ) SET TIME3=%TIME:~,8% IF "%TIME3:~,1%"==" " (SET TIME3=0%TIME3:~-7%) CLS & ECHO. & ECHO Создавалка плейлистов .mpcpl для Media Player Classic - Home Cinema ECHO. & ECHO Базовый каталог - %BaseDir% ECHO. & ECHO %TIME1% - %TIME2% Старые плейлисты убил. ECHO %TIME2% - %TIME3% Новые плейлисты создал. SET ENDTIME=%TIME:~,8% IF "%ENDTIME:~,1%"==" " (SET ENDTIME=0%ENDTIME:~-7%) SET ENDDATETIME=%DATE% %ENDTIME% ECHO Set objShell=CreateObject^(^"Wscript.Shell^"^) > Interval.vbs ECHO Interval = CDate^(CDate^(^"%ENDDATETIME%^"^) - CDate^(^"%STARTDATETIME%^"^)^) >> Interval.vbs ECHO Wscript.Echo Interval >> Interval.vbs FOR /F %%A IN ('CSCRIPT //NOLOGO "Interval.vbs"') DO SET INTERVAL=%%A: DEL /Q Interval.vbs SET INTERVAL=%INTERVAL:~0,8% IF "%INTERVAL:~7,1%" == ":" (SET INTERVAL=0%INTERVAL:~0,7%) IF "%INTERVAL:~2,1%" == "." (SET INTERVAL=Более суток) ECHO. ECHO Общее время работы ^> %STARTTIME% - %ENDTIME% = %INTERVAL% ECHO. EXIT :111 IF /I "%N%"=="1" (EXIT /B 1) EXIT /B 0
0
|
Модератор
5197 / 2079 / 406
Регистрация: 06.01.2013
Сообщений: 4,793
|
|
01.11.2013, 22:13 | 18 |
Я бы не делал проверку счетчиков, а просто сначала бы для каждого плейлиста вписывал MPCPLAYLIST, а потом файлы. И зачем 42 строка, непонятно. А так код прекрасен :-)
0
|
3 / 3 / 0
Регистрация: 31.10.2013
Сообщений: 25
|
|
01.11.2013, 22:50 [ТС] | 19 |
Дело в том, что не в каждой директории есть файлы, тем более с нужными расширениями. Проверяя счётчик я гарантированно создаю плейлист только если есть хотя бы один правильный файл.
42 строка помещает в переменную %%C очередное имя файла с полным путём, я потом в 44-й строке сравниваю значение из таблицы с %:~xC - расширением этого файла. Кстати, 42 и 44 строки не годятся - только что обнаружил. Если в пути или имени файла есть хоть один пробел, то %:~C=="" Щас что-то буду с этим думать. Добавлено через 5 минут А, тю, ну так "DELIMS=" забыл. 42 строка правильнее так: Код
FOR /F "DELIMS=" %%C IN ("%%B") DO ( Код
FOR /F "DELIMS=" %%I IN ("%%B") DO (
0
|
Модератор
5197 / 2079 / 406
Регистрация: 06.01.2013
Сообщений: 4,793
|
|
01.11.2013, 23:09 | 20 |
А почему Вы не хотите использовать %%~xB, а делаете сначала присваивание его в %%С?
0
|
01.11.2013, 23:09 | |
01.11.2013, 23:09 | |
Помогаю со студенческими работами здесь
20
Delims: разделитель из двух символов при делении по токенам Howto: os.path.dirname(sys.argv[0]) from argparse Когда следует использовать dirname(__FILE__) или $_SERVER['DOCUMENT_ROOT']? dirname возвращает строку с обратными слешами из-за чего ссылка не рабоатает? ftp-server, dir-300, dir-320. Локальная сеть. DIR-100+DIR-300= &%#@@#%!$ как же так? Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |