运行 7zip 的 Windows 批处理脚本需要文件而不是文件夹名称



我有一个批处理脚本,可以很好地压缩目录中的文件夹,但由于某种原因,在我更改名称后,它似乎正在寻找一个"文件"来压缩和密码保护,而不是"文件夹"我找不到它在源目录中压缩文件夹所需的语法

@ECHO ON
SET SourceDir=C:jobFolder
SET DestDir=C:job
CD /D "C:Program Files7-Zip"
FOR /F "TOKENS=*" %%F IN ('DIR /B /A-D "%SourceDir%"') DO (
7z.exe a "%DestDir%%%~NF" -p247BRIDGES "%SourceDir%%%NXF"
)
EXIT

这帮助了我,将.zip添加到目标并压缩文件夹中的文件

@ECHO ON
SET SourceDir=C:foldersource
SET DestDir=C:folderdestination
CD /D "C:Program Files7-Zip"
FOR /F "TOKENS=*" %%F IN ('DIR /B /A-D "%SourceDir%"') DO (
7z.exe a "%DestDir%%%~NF.zip" "%SourceDir%%%~NXF"
)
EXIT

目前还不清楚应该压缩到存档文件中的内容:目录还是文件。

该代码绝对是为将文件压缩为存档文件而编写的。

主要错误是%%NXF中缺少~,这应该%%~nxF甚至更好%%F.

但是还有一些不太明显的错误,可能会导致某些文件的错误处理。

这种情况非常罕见,但文件名可能以一个或多个前导空格或分号开头。默认eol=;会导致忽略以分号开头的DIR输出的文件名。因此,最好使用例如eol=|因为没有文件/文件夹名称可以包含垂直条。最好使用delims=而不是使用TOKENS=*从一行中删除所有前导空格/制表符并将带有空格和制表符的行的其余部分分配给指定的循环变量F以避免此批处理文件正确处理带有前导空格的文件名。

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

命令FORcmd.exe /C(更准确地说是%ComSpec% /C)开头,在后台执行命令行的单独命令进程:

dir "C:jobFolder" /A-D /B 2>nul

DIR输出,用于处理已启动命令进程的STDOUT

  • 由于选项/B,以裸格式
  • 由于选项/A-D(属性不是目录),只有带有扩展名的文件的名称
  • 匹配隐式使用的通配符模式*
  • 可在目录C:jobFolder中找到
  • 还包括具有隐藏属性集的文件。

文件名由DI"R输出,即使包含空格或这些字符之一,&()[]{}^=;!'+,`~也没有文件路径,因此也不使用选项/S(包括子目录)。

可能是DIR在目录中找不到任何与条件匹配的文件C:jobFolder在这种情况下,它会输出错误消息来处理STDERR。通过将其重定向到设备NUL来禁止显示此错误消息。

阅读有关使用命令重定向运算符的Microsoft文章,了解2>nul的说明。当 Windows 命令解释器在执行命令 FOR 之前处理此命令行时,重定向运算符>必须使用插入符号^FOR进行转义,该命令使用在后台启动的单独命令进程执行嵌入式dir命令行

FOR捕获输出以处理已启动命令进程的STDOUT,并在启动cmd.exe终止后逐行处理捕获的文本。

带有选项的 FOR/F始终忽略此处未出现的空行。默认情况下,FOR也忽略以;开头的行,因为这是默认的行尾字符,这是使用eol=|的原因,因为根本没有文件名可以包含|。默认情况下,FOR使用普通空格和水平制表符作为字符串分隔符将一行拆分为子字符串(标记),并仅将第一个空格/制表符分隔的字符串分配给指定的循环变量。如果文件名包含一个或多个空格,则此处不需要此行拆分行为。出于这个原因,delims=用于指定一个空的分隔符列表,该列表完全禁用分行行为,因此会导致将整行(= 带有扩展名的文件名,没有路径)分配给指定的循环变量。

FOR针对分配给循环变量的每个文件名运行I应用程序 7-Zip 使用默认选项压缩以完整限定文件名指定的文件作为最后一个参数字符串到目标文件夹中受密码保护的存档文件中,压缩文件的名称作为存档文件名和文件扩展名附加7-Zip

几乎相同的任务可以更快地完成:

@for %%I in ("C:jobFolder*") do @"%ProgramFiles%7-Zip7z.exe" a -p247bridges -y -- "C:job%%~nI" "%%I"

这个专为在批处理文件中使用而设计的单一命令行版本仅处理目录C:jobFolder中的所有非隐藏文件,而上述批处理文件还处理具有隐藏属性集的文件。

在这种情况下,FOR自行搜索目录C:jobFolder中的非隐藏文件,并将完整的限定文件名(文件路径 + 文件名 + 文件扩展名)分配给循环变量I并运行7-Zip将此文件压缩到存档文件中的目录C:job存档文件名与压缩文件名相同。

添加开关-y是为了防止7-Zip的任何提示,例如在存档文件上创建目标目录中已经存在的。

FOR分配循环变量I目录C:jobFolder中找到的每个文件的完整限定文件名,因为在通配符模式中使用了完全限定路径。FOR将只将文件扩展名分配给循环变量,仅使用*而不是C:jobFolder*来查找当前目录中的非隐藏文件。如果圆括号中的通配符模式是用相对路径而不是绝对路径指定的,FOR会将找到的文件的文件名分配给循环变量。最后但不列出,也可以指定多个通配符模式,每个通配符模式没有路径或相对路径或绝对路径,FOR将处理所有通配符模式。

在 Windows x64上打开 x64 命令提示符窗口并运行以下两个命令,以更好地了解FOR根据通配符模式集分配给指定循环变量I的内容:

cd /D %SystemRoot%
for %I in (*.exe System32cm*.exe %SystemRoot%SysWOW64cm*.exe) do @echo %I

输出是Windows目录被C:Windows引用%SytemRoot%所有文件扩展名.exe的非隐藏可执行文件的文件名

  • 在 Windows 目录中找不到的路径是与模式*匹配的当前目录,并且
  • 其中文件名以cm开头,在 x64 应用程序的系统目录中找到相对路径System32与模式System32cm*.exe匹配和
  • 其中文件名以cm开头,绝对路径C:WindowsSysWOW64在 x86 应用程序的系统目录中找到,与模式C:WindowsSysWOW64cm*.exe匹配。

但是如何将目录而不是文件压缩到存档文件中呢?

好吧,在第一个批处理文件中,将/A-D(属性 NOT 目录)替换为/AD(属性目录)以处理C:jobFolder中的所有子目录,包括隐藏的子目录,并将附加到7-Zip的最后一个参数,或使用开关-r进行递归压缩,甚至两者兼而有之。

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

在单命令行解决方案中,在for%%I之间插入选项/D,以处理C:jobFolder中的所有子目录,隐藏子目录除外,并修改如上所述的7-Zip参数列表。

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

打开命令提示符窗口,在那里执行以下命令,并非常仔细地阅读为每个命令显示的所有帮助页面。

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

有关从命令行使用 7-Zip 的帮助,请在 7-Zip的程序文件目录中双击其 *.chm 文件或启动7-Zip的 GUI 版本并打开帮助(相同的帮助文件),选择第一个选项卡内容,双击列表项命令行版本阅读引用的帮助页面。

最新更新