Пакетный скрипт Windows, выполняющий ожидающий файл 7zip, а не имена папок - PullRequest
0 голосов
/ 13 декабря 2018

У меня есть пакетный скрипт, который прекрасно работал, архивируя папку в каталоге, но по какой-то причине после того, как я произвел изменение имени, он, похоже, ищет "файл" для защиты от зашифрования и пароля, а не "папка "я не могу найти синтаксис, необходимый для того, чтобы он заархивировал папку в исходном каталоге

@ECHO ON
SET SourceDir=C:\job\Folder
SET DestDir=C:\job

CD /D "C:\Program Files\7-Zip"
FOR /F "TOKENS=*" %%F IN ('DIR /B /A-D "%SourceDir%"') DO (
7z.exe a "%DestDir%\%%~NF" -p247BRIDGES "%SourceDir%\%%NXF"
)
EXIT

Ответы [ 2 ]

0 голосов
/ 15 декабря 2018

Неясно, что должно быть сжато в архивные файлы: каталоги или файлы.

Код определенно написан для сжатия файлов в архивные файлы.

Основная ошибка - пропущенные ~ in %%NXF, который должен быть %%~nxF или даже лучше просто %%F.

Но есть еще некоторые не столь очевидные ошибки, которые могут привести к неправильной обработке некоторых файлов.

Очень редко, но тем не менее возможно, что имя файла начинается с одного или нескольких начальных пробелов или точки с запятой.Значение по умолчанию eol=; приводит к игнорированию имен файлов, выводимых DIR , начиная с точки с запятой.Так что было бы лучше использовать, например, eol=|, поскольку имя файла / папки не может содержать вертикальную черту.И было бы лучше использовать delims= вместо использования TOKENS=*, удалив все начальные пробелы / табуляции из строки и присвоив остальную часть строки с пробелами и табуляцией указанной переменной цикла F, чтобы избежать имен файлов с ведущимипробел неправильно обрабатывается этим пакетным файлом.

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SourceDir=C:\job\Folder"
set "DestDir=C:\job"
for /F "eol=| delims=" %%I in ('dir "%SourceDir%" /A-D /B 2^>nul') do "%ProgramFiles%\7-Zip\7z.exe" a -p247bridges -- "%DestDir%\%%~nI" "%SourceDir%\%%I"
endlocal

Команда FOR начинается с cmd.exe /C (точнее %ComSpec% /C) отдельного командного процесса в фоновом режиме для выполнения командыстрока:

dir "C:\job\Folder" /A-D /B 2>nul

DIR вывод для обработки STDOUT запущенного командного процесса

  • в голом формате из-за опции /B
  • только имена файлов с расширением из-за опции /A-D (атрибут не каталог)
  • , совпадающей с неявно используемым шаблоном подстановки *
  • , которые находятся в каталогеC:\job\Folder
  • с включением также файлов со скрытым набором атрибутов.

Имена файлов выводятся с помощью DIR всегда без " даже при наличии пробелаили же один из этих символов &()[]{}^=;!'+,`~ и без пути к файлу из-за опции /S (включая подкаталоги) тоже не используется.

Возможно, DIR не найдет файл вкаталог C:\job\Folder, соответствующий критериям; в этом случае выводится сообщение об ошибке для обработки STDERR .Это сообщение об ошибке подавляется путем перенаправления его на устройство NUL .

Прочтите статью Microsoft о Использование операторов перенаправления команд для объяснения 2>nul.Оператор перенаправления > должен быть экранирован с помощью символа вставки ^ в командной строке FOR , чтобы интерпретироваться как литеральный символ, когда интерпретатор команд Windows обрабатывает эту командную строку перед выполнением команды FOR , котораявыполняет встроенную командную строку dir в отдельном командном процессе, запущенном в фоновом режиме.

FOR захватывает выходные данные для обработки STDOUT запущенного командного процесса и обрабатывает захваченныйтекст построчно после начала cmd.exe прекращается.

FOR с параметром /F игнорирует всегда пустые строки, которые здесь не встречаются. FOR по умолчанию игнорирует также строки, начинающиеся с ;, поскольку они являются символом конца строки по умолчанию, что является причиной использования eol=|, поскольку имя файла вообще не может содержать |FOR по умолчанию разбивает строку на подстроки (токены), используя обычный пробел и горизонтальную табуляцию в качестве разделителей строк, и присваивает только первую строку с пробелом / табуляцией в указанной переменной цикла.Такое поведение разделения строк здесь не требуется, если имя файла содержит один или несколько пробелов.По этой причине delims= используется для указания пустого списка разделителей, который полностью отключает разделение строк и по этой причине приводит к получению всей строки (= имя файла с расширением без пути), назначенной указанной переменной цикла.

FOR запускается для каждого имени файла, назначенного переменной цикла I приложению 7-Zip для сжатия с параметрами по умолчанию файла, указанного с полным именем файла в качестве строки последнего аргументав защищенный паролем архивный файл в папке назначения с именем сжатого файла в качестве имени файла архива и расширением файла, добавленным 7-Zip .

Почти ту же задачу можно выполнить чуть быстрееwith:

@for %%I in ("C:\job\Folder\*") do @"%ProgramFiles%\7-Zip\7z.exe" a -p247bridges -y -- "C:\job\%%~nI" "%%I"

Эта версия для командной строки, предназначенная для использования в пакетном файле, обрабатывает только все не скрытые файлы в каталоге C:\job\Folder по сравнению с вышеуказанным пакетным файлом, который обрабатывает также файлы со скрытым набором атрибутов.

FOR ищет в этом случае не скрытые файлы в каталоге C:\job\Folder и присваивает полное имя файла (путь к файлу + имя файла + расширение файла) переменной цикла I и запускает 7-Zip для сжатия этого файла в файл архива в каталог C:\job с именем файла архивасовпадает с именем сжатого файла.

Переключатель -y добавлен для предотвращения любого запроса 7-Zip , например, для файла архива, чтобы создать уже существующий вкаталог назначения.

FOR назначает переменной цикла I полное имя файла для каждого найденного файла в каталоге C:\job\Folder из-за использования полного пути в шаблоне с подстановочными знаками. FOR присваивает переменной цикла только имя файла с расширением файла при использовании просто * вместо C:\job\Folder\* для поиска не скрытых файлов в текущем каталоге.И FOR назначит переменной цикла имя файла найденного файла с относительным путем, если шаблон с подстановочными знаками в круглых скобках указан с относительным, а не абсолютным путем.Последний, но не список, можно также указать несколько шаблонов подстановок, каждый из которых не содержит ни пути, ни относительного пути, ни абсолютного пути, и FOR обработает все шаблоны.

ОткройтеОкно командной строки x64 в Windows x64 и выполните следующие две команды, чтобы лучше понять, что FOR назначает указанной переменной цикла I в зависимости от набора шаблонов подстановочных знаков:

cd /D %SystemRoot%
for %I in (*.exe System32\cm*.exe %SystemRoot%\SysWOW64\cm*.exe) do @echo %I

Вывод с каталогом Windows C:\Windows со ссылкой %SytemRoot% имена файлов всех не скрытых исполняемых файлов с расширением файла .exe

  • без указания пути в каталоге Windows, являющегося текущим каталогом, которому соответствуетшаблон * и
  • , имя файла которого начинается с cm с относительным путем System32\ в системном каталоге для приложений x64, соответствующих шаблону System32\cm*.exe и
  • , имя файланачинается с cm с абсолютного пути C:\Windows\SysWOW64\ в системном каталоге для приложений x86, соответствующих шаблону C:\Windows\SysWOW64\cm*.exe.

Но как сжать каталоги вместо файлов в архивные файлы?

Что ж, в первом пакетном файле замените /A-D (атрибут NOT directory) на /AD (атрибут directory) наобработать все подкаталоги в C:\job\Folder, включая скрытые подкаталоги, и либо добавить \ к последнему аргументу 7-Zip , либо использовать переключатель -r для рекурсивного сжатия, либо даже оба.

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SourceDir=C:\job\Folder"
set "DestDir=C:\job"
for /F "eol=| delims=" %%I in ('dir "%SourceDir%" /AD /B 2^>nul') do "%ProgramFiles%\7-Zip\7z.exe" a -p247bridges -r -- "%DestDir%\%%~nI" "%SourceDir%\%%I\"
endlocal

И в едином решении командной строки вставьте опцию /D между for и %%I, чтобы обработать все подкаталоги в C:\job\Folder за исключением скрытых подкаталогов и изменить также 7-Zip список параметров, как указано выше.

@for /D %%I in ("C:\job\Folder\*") do @"%ProgramFiles%\7-Zip\7z.exe" a -p247bridges -r -y -- "C:\job\%%~nI" "%%I\"

Откройте окно командной строки, выполните там следующие команды и полностью прочитайте все страницы справки, отображаемые для каждой команды.

  • cd /?
  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • set /?
  • setlocal /?

Для получения справки по использованию 7-Zip из командной строки дважды щелкните его * .chm файл в каталоге программных файлов 7-Zip или запустите версию GUI 7-Zip и откройте справку (тот же файл справки), выберите первую вкладку Содержание , дважды щелкните элемент списка Версия командной строки и прочитайте справочные страницы справки.

0 голосов
/ 14 декабря 2018

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

 @ECHO ON

 SET SourceDir=C:\folder\source
 SET DestDir=C:\folder\destination

 CD /D "C:\Program Files\7-Zip"
 FOR /F "TOKENS=*" %%F IN ('DIR /B /A-D "%SourceDir%"') DO (
 7z.exe a "%DestDir%\%%~NF.zip" "%SourceDir%\%%~NXF"
 )
 EXIT
...