PDA

Показать полную графическую версию : [решено] Проверка архива zip на наличие определенных файлов


FantomasAnand
07-11-2017, 18:13
Добрый день!

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

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

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

alpap
09-11-2017, 12:38
обязательное присутствие обоих файлов в архиве »
это тоже важно
для всех архивов идентичная проверка или для каждого своя »
т.е. файлы именно: a.txt и b.txt должны оба присутствовать в каждом архиве или в другом архиве будут c.txt и d.txt, в третьем 1.txt и 2.txt

Iska
09-11-2017, 13:01
т.е. файлы именно: a.txt и b.txt должны оба присутствовать в каждом архиве или в другом архиве будут c.txt и d.txt, в третьем 1.txt и 2.txt »
Я понял так: есть набор архивов. Надо получить листинг оглавления каждого из архивов, и те архивы, в которых будут находиться пара искомых имён файлов, скопировать по заданному адресу. Т.е. всего два имени файлов у нас есть, и их надо найти в оглавлениях.

FantomasAnand
09-11-2017, 17:04
Iska верно. Копался, но такого никак не могу добиться.

megaloman
09-11-2017, 22:57
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
ага, уже ответили, ну приложу свой вариант раз уже начал, хотя он похож на вариант 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
ну приложу свой вариант раз уже начал, хотя он похож на вариант megaloman »Пусть расцветают сто цветов, пусть соперничают сто школ Ни у кого нет права на абсолютную истину.
findstr /c:"%zf1%" » ищем файл a.txt ? и находим tralala.txt тоже? Надо сразу ИМХО при вызове архиватора перечислить искомое.
ИМХО ....A тоже не обязательно такой атрибут.
Мне не удалось под For затолкать вызов архиватора, чтобы присвоить переменной последнюю строку листинга архиватора.
Пришлось делать промежуточный файл.
Меня это гнетёт.

alpap
10-11-2017, 12:26
и находим tralala.txt тоже? »
Да. После того как начал писать код пропало все желание делать эту задачу на cmd, поэтому и ....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
Угу. Не хватает такой простой команды как у rar — «vb», отобразить только имена с путями.

alpap
10-11-2017, 13:42
Подправил, теперь просматривает и в глубь, проверял с именами файлов внутри, архивов и папок равных: "....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
Пришлось делать промежуточный файл.
Меня это гнетёт. »

Вот без временного файла
ИДЕЯ И ПРИНЦИП КОДА РАЗРАБОТАНА 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
Пришлось делать промежуточный файл.
Меня это гнетёт. » Спасибо 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
при наличии в них повторяющихся имён файлов »
ваш здесь первый вариант тоже прекрасно справляется при наличии одинаковых файлов в разных архивах (a и b, например заданы)
1 - a b c
2 - a b
3 - b c
1 и 2 - будут сохранены, проверялось.
или что-то другое под этим имеется ввиду?

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

alpap
10-11-2017, 19:40
Ааа, вон оно что, о таком варианте я как-то даже не подумал проверить - не хватило фантазии, надо запомнить.

Iska
10-11-2017, 19:49
alpap, megaloman, не смотрел код. Возможность указать оба искомых файла в командной строке:
"C:\Program Files\7-Zip\7z.exe" l -r "Sample.7z" "File1.txt" "File2.txt"
использовалась?

megaloman
10-11-2017, 20:20
Iska, угу, мой первый вариант

alpap
10-11-2017, 23:10
Iska,
так точно пост #13




© OSzone.net 2001-2012