2015-02-17 2 views
1

Прямо сейчас у меня есть пакетный скрипт, который используется, чтобы пройти через кучу подпапок и закрепить в нем файлы журналов, папку структура в основном так:Как исключить каталог из цикла вызова dir - быстрее, чем | find/v

+---fakeG 
| +---ExclusionFolder 
| | +---LimitlessFolders 
| | +---MoreFolders 
| | \---SoManyFolders 
| +---logs1 
| +---logs2 
| +---logs3 
| +---logs4 
| +---logs5 
| \---logs6 

Каждый из этих подкаталогов должны быть пройдена, и их подпапки проходится, а также. Этот сценарий должен избегать одной конкретной папки, и он ее избегает, но использует% | найти/v. Хотя в этом примере ExclusionFolder находится в верхней части списка, в реальной структуре папки это не так.

Вот как я это сейчас:

FOR /F "delims=" %%A IN (
    'DIR "%LogsFilespec%" /B /S ^| find /v "ExclusionFolder"' 
) DO CALL :DoZip "%%~dpnA" "%%~fA" "%zipCommand%" "%zipParams%" %ProcessLog% 

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

SO: Есть ли более быстрый способ исключить папку из вызова dir без поиска?

Или мне нужно придумать совершенно другой способ сделать это?

Редактировать Извините,% LogsFileSpec℅ относится к целевому файлу. Мое первоначальное редактирование было правильным, и мое второе редактирование было неправильным.

SET LogsLocation="G:\fakeG\Data\Logs" 
SET LogsName="trace*%targetDate%.log" 
SET LogsFilespec="%LogsLocation%\%LogsName%" 

Извините, что не дал больше сценария, я решил, что вопрос не нужен.

Edit2 Процесс: DoZip работает следующим образом:

:DoZip 
:: Parameter 1 = Filename without .EXT for Archive Name 
:: Parameter 2 = Target file specifics 
:: Parameter 3 = Zip Command (Winzip/7zip64/7zip32) 
:: Parameter 4 = Zip Parameters (a -tzip, -a) 
:: Parameter 5 = ProcessLog 
setlocal 
SET archiveName=%~1 
SET SourceFileSpec=%~2 
SET zipCommand=%~3 
SET zipParms=%~4 
SET RunLog=%~5 

    ECHO %TIME% Archiving %SourceFileSpec%... 
    ECHO %TIME% Archiving %SourceFileSpec%... >> %RunLog% 

    ECHO "%zipCommand%" %zipParms% "%archiveName%.zip" "%SourceFileSpec%" 
    ECHO "%zipCommand%" %zipParms% "%archiveName%.zip" "%SourceFileSpec%" >> %RunLog% 
    "%zipCommand%" %zipParms% "%archiveName%.zip" "%SourceFileSpec%" >> %RunLog% 

:: Check errorlevel of executed command 
:: If errorlevel != 0, set EC with the errorlevel and echo that there was an error in archival 
IF NOT %ERRORLEVEL%==0 (
    ECHO ***ERROR archiving %SourceFileSpec% >>                   %RunLog% 
    SET EC=%ERRORLEVEL% 
    ECHO ***ERRORLEVEL RETURNED: %EC% >> %RunLog% 
) ELSE (
:: Otherwise, delete the file 
    ECHO. >>                               %RunLog% 
    ECHO. >>                               %RunLog% 
    ECHO %TIME% Deleting %SourceFileSpec%... 
    ECHO %TIME% Deleting %SourceFileSpec%... >>                   %RunLog% 
::Quietly delete the file 
    DEL /Q %SourceFileSpec% 

    :: Set ErrorLevel to capture the Delete command result. 
    SET EC=%ERRORLEVEL% 
) 
GOTO :EOF 

Редактировать 3 Вот zipCommand

SET PathWinZip=C:\Program Files\WinZip\wzzip.exe 
SET Path7Zip_64bit=C:\Program Files\7-Zip\7z.exe 
SET Path7Zip_32bit=C:\Program Files (x86)\7-Zip\7z.exe 

:: Check for WinZip 
IF EXIST "%PathWinZip%" SET zipCommand=%PathWinZip% & SET zipParms=-a 

:: Check for 32-bit version of 7-Zip. If found, configure 
:: its command line parameter to produce a .zip file 
IF EXIST "%Path7Zip_32bit%" SET zipCommand=%Path7Zip_32bit% & SET zipParms=a -tzip 

:: Check for 64-bit version of 7-Zip. If found, configure 
:: its command line parameter to produce a .zip file 
IF EXIST "%Path7Zip_64bit%" SET zipCommand=%Path7Zip_64bit% & SET zipParms=a -tzip 
+0

Можете ли вы указать другие файлы с более конкретным выражением, чем '% LogsFilespec%'? Например, на основе того, что вы показываете, это может быть: FOR/F ... IN ('DIR% LogsFilesspec%/logs *'/B/S '...) ... 'или что-то в этом роде. – lurker

+0

Не знаю, процедура ': DoZip': некоторые инструменты _zipping_, возможно, большинство из них, позволяют использовать _file list_ или какой-то квази-скрипт. Возможно, быстрее создать такой список (набор конкретных списков) и вызвать адаптированный ': DoZipList'? – JosefZ

+0

Просьба показать определение всех переменных и показать процедуру ': DoZip' и/или лучше описать, что вы пытаетесь сделать.Там очень хорошо может быть лучший способ выполнить вашу задачу, но вы не предоставили достаточной информации. – dbenham

ответ

2

Я считаю, что следующее должно исключать поддерево в поле:

FOR /F "delims=" %%X IN (
    'DIR /B /ad ') DO IF /i "%%X" neq "ExclusionFolder" FOR /F "delims=" %%A IN (
    'DIR /B /S "%%X\%LogsFilespec%"' 
) DO CALL :DoZip "%%~dpnA" "%%~fA" "%zipCommand%" "%zipParams%" %ProcessLog% 

То есть выполнить сканирование имени целевого объекта по каталогу; если найденный каталог не является именем exclude, тогда выполните остаток для этого подкаталога.

+0

Спасибо за ответ! Я пытаюсь это решение, но получение 'The filename, имя каталога или синтаксис метки тома неверно.' 'Имя файла, имя каталога или синтаксис метки тома неверны.' Пробовал CD'ing в каталог до цикла , просто выведите больше из них. – driftandwander

+0

Я понял, что у меня была опечатка на моем компакт-диске. Теперь его поиск всех файлов журнала, включая те, которые он не должен архивировать, НО он игнорирует ExclusionFolder! Но на самом деле это не архивирование или удаление, а просто эхо-комментарий к cmd текст, который он должен добавить в% RunLog% внутри DoZip ... – driftandwander

+0

В этом случае проблема должна быть в 'DOZIP'. Вы, кажется, говорите, что поставляемые параметры выглядят так, как вы ожидаете, поэтому проблема не связана с вашей проблемой «исключить каталог». Поскольку вы не публиковали, что такое 'zipCommand', я подозреваю, что это должен быть командный файл, поэтому' dozip' будет передавать управление этому пакетному файлу, а остаток после ''% zipCommand% "...' будет пропущен. Попробуйте 'call '% zipCommand%" ... ', чтобы предоставить' dozip' место возврата. – Magoo

1

Такой подход мог бы быть немного быстрее:

pushd "%LogsFilespec%" 
rem get subfolders of first level only 
for /f "tokens=*" %%p in (
    'DIR "%LogsFilespec%" /B /AD ^| find /v "ExclusionFolder"' 
) do ( 
    rem treat each (here will not be excluded one) 
    FOR /F "delims=" %%A IN (
     'DIR "%%~p" /B /S' 
    ) DO CALL :DoZip "%%~dpnA" "%%~fA" "%zipCommand%" "%zipParams%" %ProcessLog% 
) 
popd 
goto :eof 
0

Решение ниже не использовать одну FIND команду ни FOR /F ... один (что требует выполнения копии cmd.exe), так что я думаю, что он должен работать быстрее:

@echo off 
setlocal 

rem Enter to the base folder 
cd "%LogsFilespec%" 

rem Start the recursive process 
call :processThisDir 
goto :EOF 


:processThisDir 

rem Process the files in this folder 
for %%A in (*.*) do CALL :DoZip "%%~dpnA" "%%~fA" "%zipCommand%" "%zipParams%" %ProcessLog% 

rem Process nested subfolders, but omit "ExclusionFolder" 
for /D %%a in (*) do (
    if "%%a" neq "ExclusionFolder" (
     cd "%%a" 
     call :processThisDir 
     cd .. 
    ) 
) 
exit /B