Неясно, что должно быть сжато в архивные файлы: каталоги или файлы.
Код определенно написан для сжатия файлов в архивные файлы.
Основная ошибка - пропущенные ~
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 и откройте справку (тот же файл справки), выберите первую вкладку Содержание , дважды щелкните элемент списка Версия командной строки и прочитайте справочные страницы справки.