2016-05-05 3 views
0

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

"=="."zip" was unexpected at this time 

Ниже приводится сценарий партии, который я написал.

@echo off 
cd /d %~dp0 
for /r %%i in (*) do if %%i "%Extension%"==".zip" (
setlocal 
cd /d %~dp0 
Call :UnZipFile "G:\NewUpdates\ExtractedStuff" %%i 
exit /b 

:UnZipFile <ExtractTo> <newzipfile> 
set vbs="%temp%\_.vbs" 
if exist %vbs% del /f /q %vbs% 
>%vbs% echo Set fso = CreateObject("Scripting.FileSystemObject") 
>>%vbs% echo If NOT fso.FolderExists(%1) Then 
>>%vbs% echo fso.CreateFolder(%1) 
>>%vbs% echo End If 
>>%vbs% echo set objShell = CreateObject("Shell.Application") 
>>%vbs% echo set FilesInZip=objShell.NameSpace(%2).items 
>>%vbs% echo objShell.NameSpace(%1).CopyHere(FilesInZip) 
>>%vbs% echo Set fso = Nothing 
>>%vbs% echo Set objShell = Nothing 
cscript //nologo %vbs% 
if exist %vbs% del /f /q %vbs% 
) 
pause 

что я делаю неправильно здесь? Пожалуйста посоветуй.

+0

'% расширение%' не имеет особого смысла. Обычно вы разрешаете указанную недостающую переменную 'if"% var% "==" whatever ". Но вы хотите, чтобы '%% ~ xi' смотрел конец' for /? 'Для справки. –

+0

Или 'for/f 'delims =" %% A in (' dir/b/s c: \ somefolder \ *. Zip ') do echo %% A' См. 'Dir /?', 'For /?'. –

+0

@Noodles ', почему 'for/F'? 'for/R %% i in (* .zip) do' enough ... – aschipfl

ответ

1

Вы читаете неопределенную переменную %Extension%, и у вас есть два выражения в левой части == в операторе if, что является синтаксической ошибкой.

Чтобы получить расширение имени файла элемента итерированного по for петле, используйте ~x модификатор (тип for /? в командной строке, чтобы узнать больше о том, что), как %%~xi в вашем коде:

if /i "%%~xi"==".zip" (...) 

Переключатель /i делает сравнение нечувствительным к регистру, которое рекомендуется здесь, так как Windows обрабатывает имена файлов таким же образом.


Однако в вашей ситуации вам не нужны if заявление вообще для проверки расширения имени файла, так что вы можете позволить for сделать эту работу:

for /r %%i in (*.zip) do (...) 

Этот цикл Перебирает *.zip файлов только.


Существует еще одна проблема в вашем коде: подпрограмма :UnZipFile является частью тела цикла, и поэтому есть и exit /b внутри цикла.

Подпрограмма должна быть вне цикла. Когда выполняется call, текущие контексты заключенных в скобки блоков кода не известны в подпрограмме, поэтому он не будет считаться завершенным, как только появится завершение цикла )10, скорее возникает синтаксическая ошибка. Следовательно, вам нужно переместить ) от самого нижнего уровня до новой строки доexit /b (если вы поместите его после того, команда exit сломает цикл).

Поскольку у вас есть setlocal внутри вашего цикла, то нужно положить также endlocal (непосредственно перед )), чтобы не превысить setlocal вложенности предел.Однако, если вы используете полные пути внутри цикла, вам не нужно setlocal/endlocal. Вместо этого я переместил бы setlocal/endlocal в подпрограмму, чтобы локализовать переменные среды, используемые в ней.


Я не уверен, что если вы собираетесь перейти в каталог, где скрипт хранится на cd /d %~dp0, но я думаю, что вы хотите полный путь к текущей итерации *.zip файла в цикле, не так ли? Если да, удалите команду cd и используйте %%~fi в командной строке call.


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

Также в подпрограммах следует процитировать пути, предоставленные в качестве аргументов, и доступ к ним, как "%~1", например, чтобы получить их цитироваться (тип call /?, чтобы увидеть, что ~ удаляет окружающие кавычки potentionally доставлены в командной строке).

И лучший set синтаксис: set "vbs=%temp%\_.vbs"; поэтому котировки не становятся частью стоимости, и у вас всегда есть один место для размещения кавычек - а именно, когда чтение (расширение) переменной, например "%vbs%".


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


Вот фиксированный код:

@echo off 
cd /d %~dp0 
for /r %%i in ("*.zip") do (
    Call :UnZipFile "G:\NewUpdates\ExtractedStuff" "%%~fi" 
) 
exit /b 

:UnZipFile <ExtractTo> <newzipfile> 
    setlocal 
    set vbs="%temp%\_.vbs" 
    if exist "%vbs%" del /f /q "%vbs%" 
    >"%vbs%" echo Set fso = CreateObject("Scripting.FileSystemObject") 
    >>"%vbs%" echo If NOT fso.FolderExists("%~1") Then 
    >>"%vbs%" echo fso.CreateFolder("%~1") 
    >>"%vbs%" echo End If 
    >>"%vbs%" echo set objShell = CreateObject("Shell.Application") 
    >>"%vbs%" echo set FilesInZip=objShell.NameSpace("%~2").items 
    >>"%vbs%" echo objShell.NameSpace("%~1").CopyHere(FilesInZip) 
    >>"%vbs%" echo Set fso = Nothing 
    >>"%vbs%" echo Set objShell = Nothing 
    cscript //nologo "%vbs%" 
    if exist "%vbs%" del /f /q "%vbs%" 
    endlocal 
    pause 
+0

эй, как я могу извлечь zip-файлы подпапок в самих подпапках? В настоящее время папка G: \ NewUpdates \ ExtractedStuff имеет 3 подпапки, и мне нужно извлечь соответствующие zip-файлы в папки, которые они сейчас сами. Это G: \ NewUpdates \ ExtractedStuff \ updater \ test.zip следует извлечь в G: \ NewUpdates \ ExtractedStuff \ updater \. Я попробовалCall: UnZipFile %% ~ pi "%% ~ fi", но его не работает :( – mayooran

+0

Также есть способ сделать вывод без звука? Я хочу, чтобы он перезаписывал существующие файлы без портирования меня чем-нибудь – mayooran

+0

Я думаю, что 'call' Командная строка должна быть изменена для извлечения в папку, в которой находится ZIP-файл: 'Call: UnZipFile '%% ~ dpi."" %% ~ fi "'; в вашей попытке нет буквы диска ('~ d'), нет кавычек и при использовании' ~ p'/'~ dp существует хвост' \ ', который также может вызвать проблемы (поэтому я добавил «.»), я не знаю, как выполнить бесшумное извлечение, но без подсказки, но вы можете принудительно удалить содержимое папки назначения (за исключением самого ZIP, конечно, если оно находится в каталог назначения также) командой 'del' (могут также помочь переключатели'/S' и '/ Q') ... – aschipfl

0

Мой совет, чтобы упростить поиск архивных файлов путем фильтрации их в для команды, а не проверять расширения файлов

Используйте следующую команду:

for /f "tokens=*" %%a in ('dir /a:-d /b ^| findstr /r ".zip$"') do echo %%a 

Эта команда выведет список всех почтовый индекс файлы в вашем каталоге, теперь вы можете играть с ними так, как вы хотите

Надеюсь, это поможет.

+0

Что относительно файлов с расширением '.ZIP'? Бьюсь об заклад, они не будут найдены ... – aschipfl