Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Проверка архива zip на наличие определенных файлов (http://forum.oszone.net/showthread.php?t=331054)

FantomasAnand 07-11-2017 18:13 2775984

Проверка архива zip на наличие определенных файлов
 
Добрый день!

В папке хранятся много zip архивов. Нужно сделать скрипт проверки zip архивов на наличие в нем Файла1 & Файла2. Если такой архив находится, то копировать его в другую папку.

alpap 07-11-2017 18:28 2775987

Файла1 и Файла2 - есть
Файла1 - есть, Файла2 - нет
Файла1 - нет, Файла2 - есть
Файла1 и Файла2 - нет
какой вариант?
когда ответите, подумайте: для всех архивов идентичная проверка или для каждого своя, совпасть должно имя.расширение файла(ов) или кол-во (есть 1 файл или 2 или ни одного)

FantomasAnand 09-11-2017 11:43 2776340

Файла1 и Файла2 - есть.
в архиве должны быть как минимум 2 файла с определенными именами. Условие : обязательное присутствие обоих файлов в архиве с определенными именами.

alpap 09-11-2017 12:38 2776361

Цитата:

Цитата FantomasAnand
обязательное присутствие обоих файлов в архиве »

это тоже важно
Цитата:

Цитата alpap
для всех архивов идентичная проверка или для каждого своя »

т.е. файлы именно: a.txt и b.txt должны оба присутствовать в каждом архиве или в другом архиве будут c.txt и d.txt, в третьем 1.txt и 2.txt

Iska 09-11-2017 13:01 2776375

Цитата:

Цитата alpap
т.е. файлы именно: a.txt и b.txt должны оба присутствовать в каждом архиве или в другом архиве будут c.txt и d.txt, в третьем 1.txt и 2.txt »

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

FantomasAnand 09-11-2017 17:04 2776425

Iska верно. Копался, но такого никак не могу добиться.

megaloman 09-11-2017 22:57 2776522

FantomasAnand, Архиватора Zip у меня нет. Попробуйте. Не знаю, насколько код чувствителен к версии 7z. Я предположил, что в каждом архиве искомые имена уникальны, то есть не повторяются. Если это не так, можно переделать
Код:

@Echo Off

Set "FileIn=Z:\Box_In\*.zip"

Set "Exists="data1.cab" "data2.cab""
Set /A NExists=2

Set "BoxOut=Z:\Box_Out"

Set "Arc="C:\Program Files\7-Zip\7z.exe" l -r"

Set "FileTmp=%Tmp%\%~nx0.tmp"
FOR /F "usebackq delims=" %%i IN (`dir "%FileIn%" /S /B /A:-D 2^>nul`) DO Call :CheckZip "%%i"
Del "%FileTmp%" 2>nul

GoTo :Eof

:CheckZip
        %Arc% %1 %Exists% >"%FileTmp%"
        Set /A N=0
        FOR /F "usebackq tokens=5 delims= " %%s IN ("%FileTmp%") DO Set /A N=%%s 2>nul
        If %N% GEQ %NExists% Copy %1 "%BoxOut%" >nul
GoTo :Eof


alpap 09-11-2017 23:58 2776535

ага, уже ответили, ну приложу свой вариант раз уже начал, хотя он похож на вариант megaloman, но как раз учитывал повторяемость файлов, т.е. должно быть минимум два заданных, допускается более 2х, но не менее, но эти 2 обязательно

"a.txt" и "b.txt" - если как минимум эти два файла будут в архиве, то все такие архивы будут сохранены в папку "C:\b_arch"

Код:

@echo off
set "d_out=C:\b_arch"
set "exp=7z"
set "ar=%ProgramFiles%\7-Zip\7z.exe"
set "zf1=a.txt"& set "zf2=b.txt"

if not exist "%d_out%" md "%d_out%"
for /f "delims=" %%A in ('2^>nul dir /a-d/b "*.%exp%"') do (
 setlocal enabledelayedexpansion
  for /f "tokens=5*" %%a in ('"%ar%" l "%%A"^|findstr /c:" ....A "^|findstr /c:"%zf1%" /c:"%zf2%"') do set /a n+=1& set "a!n!=%%A"
  if not "!a2!"=="" >nul copy "!a2!" "%d_out%"
 endlocal
)
pause


megaloman 10-11-2017 00:34 2776538

Цитата:

Цитата alpap
ну приложу свой вариант раз уже начал, хотя он похож на вариант megaloman »

Цитата:

Цитата Мао Дзе Дун
Пусть расцветают сто цветов, пусть соперничают сто школ

Ни у кого нет права на абсолютную истину.
Цитата:

Цитата alpap
findstr /c:"%zf1%" »

ищем файл a.txt ? и находим tralala.txt тоже? Надо сразу ИМХО при вызове архиватора перечислить искомое.
ИМХО ....A тоже не обязательно такой атрибут.
Мне не удалось под For затолкать вызов архиватора, чтобы присвоить переменной последнюю строку листинга архиватора.
Пришлось делать промежуточный файл.
Меня это гнетёт.

alpap 10-11-2017 12:26 2776616

Цитата:

Цитата megaloman
и находим tralala.txt тоже? »

Да. После того как начал писать код пропало все желание делать эту задачу на cmd, поэтому и
Цитата:

Цитата megaloman
....A тоже »

и -r не использовал, да что там говорить, здесь имена заданы и найти их можно постаравшись, а вот вывести все имена чтобы можно было с ними работать мне когда-то пришлось такую конструкцию писать:
Код:

@echo off
set "exp=7z"
set "arch=%ProgramFiles%\7-Zip\7z.exe"
for /f "delims=" %%a in ('dir /a-d/b "*.%exp%"') do call :# "%%a"
pause& exit

:#
 setlocal enabledelayedexpansion
  for /f "delims=:" %%a in ('""%arch%" l "%~1"|findstr /rn /c:"^---""') do set /a n+=1& set "v!n!=%%a"& set /a "nd=v1+1,kd=v2-1" 
  for /f "tokens=5*" %%a in ('"for /l %%a in (!nd!,1,!kd!) do @"%arch%" l "%~1"|find /n /v ""|find "[%%a]""') do echo %%b
 endlocal
exit /b

Это мыслимо? Это просто вывод имен!

Iska 10-11-2017 13:11 2776629

Угу. Не хватает такой простой команды как у rar — «vb», отобразить только имена с путями.

alpap 10-11-2017 13:42 2776636

Подправил, теперь просматривает и в глубь, проверял с именами файлов внутри, архивов и папок равных: "....A", единственно очень точным совпадением имен не утруждался
Код:

@echo off
set "d_out=C:\b_arch"
set "exp=7z"
set "ar=%ProgramFiles%\7-Zip\7z.exe"
set "zf1=a.txt"& set "zf2=b.txt"

if not exist "%d_out%" md "%d_out%"
for /f "delims=" %%A in ('dir /a-d/b/s "*.%exp%"') do (
 setlocal enabledelayedexpansion
  for /f "tokens=5*" %%a in ('""%ar%" l -r "%%A"|findstr /r /c:"\^<%zf1%$" /c:"\^<%zf2%$""') do set /a n+=1& set "a!n!=%%A"
  if not "!a2!"=="" >nul copy "!a2!" "%d_out%"
 endlocal
)
pause


alpap 10-11-2017 15:35 2776666

Цитата:

Цитата megaloman
Пришлось делать промежуточный файл.
Меня это гнетёт. »

Вот без временного файла
ИДЕЯ И ПРИНЦИП КОДА РАЗРАБОТАНА megaloman - Благодарности ему.
(я только убрал временный файл и немного подрихтовал)
Код:

@echo off
set "d_out=C:\b_arch"
set "exp=7z"
set "ar=%ProgramFiles%\7-Zip\7z.exe"
set "zf1=a.txt"& set "zf2=b.txt"

for /f "delims=" %%a in ('2^>nul dir /a-d/b/s "*.%exp%"') do call :# "%%a" "%d_out%" "%zf1%" "%zf2%" "%ar%"
pause& exit

:# [Архив] [Путь сохранения] [Файл1] [Файл2] [Архиватор]
 for /f "tokens=5" %%a in ('""%~5" l -r "%~1" "%~3" "%~4""') do 2>nul set /a n=%%a
 if %n% geq 2 (if not exist "%~2" md "%~2")& >nul copy "%~1" "%~2"
exit /b


megaloman 10-11-2017 18:03 2776690

Цитата:

Цитата megaloman
Пришлось делать промежуточный файл.
Меня это гнетёт. »

Спасибо alpap, подсмотрел как под For затолкать вызов архиватора.
мой исправленный вариант без промежуточного файла
Код:

@Echo Off

Set "FileIn=Z:\Box_In\*.zip"

Set "Exists="data1.cab" "data2.cab""
Set /A NExists=2

Set "BoxOut=Z:\Box_Out"

Set "Arc="C:\Program Files\7-Zip\7z.exe" l -r"

FOR /F "usebackq delims=" %%i IN (`dir "%FileIn%" /S /B /A:-D 2^>nul`) DO Call :CheckZip "%%i"
GoTo :Eof

:CheckZip
        FOR /F "tokens=5 delims= " %%s IN ('"%Arc% %1 %Exists%"') DO Set /A N=%%s 2>nul
        If %N% GEQ %NExists% Copy %1 "%BoxOut%" >nul
GoTo :Eof

В моём варианте может рассматриваться одновременное наличие нескольких файлов, в частности, двух:
параметры:
Set "Exists="data1.cab" "data2.cab""
Set /A NExists=2
Вот вариант, который правильно обрабатывает архивы даже при наличии в них повторяющихся имён файлов
Код:

@Echo Off

Set "FileIn=Z:\Box_In\*.zip"
Set "Exists="data1.cab" "data2.cab" "setup.exe""

Set "BoxOut=Z:\Box_Out"

Set "Arc="C:\Program Files\7-Zip\7z.exe" l -r"

FOR /F "usebackq delims=" %%i IN (`dir "%FileIn%" /S /B /A:-D 2^>nul`) DO Call :FilesExists "%%i"
GoTo :Eof

:FilesExists
        FOR %%f IN (%Exists%) DO Call :CheckZip %1 "%%~f" &&GoTo :Eof
        Copy %1 "%BoxOut%" >nul
GoTo :Eof

:CheckZip
        Set /A N=0
        FOR /F "tokens=5 delims= " %%s IN ('"%Arc% %1 %2"') DO Set /A N=%%s 2>nul
Exit /B %N%

Здесь для примера приведено наличие трёх файлов
Set "Exists="data1.cab" "data2.cab" "setup.exe""

alpap 10-11-2017 19:29 2776705

Цитата:

Цитата megaloman
при наличии в них повторяющихся имён файлов »

ваш здесь первый вариант тоже прекрасно справляется при наличии одинаковых файлов в разных архивах (a и b, например заданы)
1 - a b c
2 - a b
3 - b c
1 и 2 - будут сохранены, проверялось.
или что-то другое под этим имеется ввиду?

megaloman 10-11-2017 19:36 2776707

alpap, Пусть имеется архив с множеством папок. В разных папках в этом архиве присутствует файл а, например. То есть мы его нашли там несколько раз, зато ни разу не нашли, допустим, b. Первый вариант это с радостью проглотит как искомый. А условие-то: одновременное наличие а и b. В данном случае важно знать характер архива. Если нет повторяющихся файлов в разных папках архива, то первый вариант работает быстрее. Второй вариант по отдельности выискивает каждый файл в архиве, то есть приходится в худшем случае архиватор вызывать несколько раз для каждого архивного файла.

alpap 10-11-2017 19:40 2776708

Ааа, вон оно что, о таком варианте я как-то даже не подумал проверить - не хватило фантазии, надо запомнить.

Iska 10-11-2017 19:49 2776714

alpap, megaloman, не смотрел код. Возможность указать оба искомых файла в командной строке:
Код:

"C:\Program Files\7-Zip\7z.exe" l -r "Sample.7z" "File1.txt" "File2.txt"
использовалась?

megaloman 10-11-2017 20:20 2776726

Iska, угу, мой первый вариант

alpap 10-11-2017 23:10 2776765

Iska,
так точно пост #13


Время: 13:42.

Время: 13:42.
© OSzone.net 2001-