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

时间:2018-12-13 20:37:40

标签: batch-file command-line

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

@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 :(得分:0)

这对我有所帮助,方法是将.zip添加到目标位置,然后将文件压缩到文件夹中

y | mv srcdir/* targetdir/

答案 1 :(得分:0)

尚不清楚应压缩到存档文件中的内容:目录或文件。

代码绝对是用于将文件压缩为存档文件的。

主要错误是~中缺少的%%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 输出,即使包含空格或这些字符之一",也始终不带&()[]{}^=;!'+,`~,并且由于选项{{1}而没有文件路径}(包括子目录)也未使用。

DIR 可能在目录/S中找不到符合条件的文件,在这种情况下,它会输出一条错误消息来处理 STDERR 。通过将其重定向到设备 NUL ,可以抑制此错误消息。

阅读有关Using Command Redirection Operators的Microsoft文章,以获取C:\job\Folder的解释。当Windows命令解释器在执行命令之前处理此命令行时,重定向操作符2>nul必须在 FOR 命令行上使用脱字符号>进行转义,才能被解释为文字字符。 FOR ,它将在后台启动的单独命令进程中执行嵌入式^命令行。

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

带有选项cmd.exe

FOR 总是忽略在这里不出现的空行。 FOR 默认情况下也会忽略以/F开头的行,因为这是默认的行尾字符,这是使用;的原因,因为没有文件名可以包含{{ 1}}。默认情况下, FOR 使用正常空格和水平制表符作为字符串定界符,将行拆分为子字符串(令牌),并仅将第一个空格/制表符分隔的字符串分配给指定的循环变量。如果文件名包含一个或多个空格,则在此不需要行拆分行为。出于这个原因,eol=|用于指定一个空的定界符列表,该列表将完全禁用行分割行为,并因此导致将整行(=扩展名不带路径的文件名)分配给指定的循环变量。

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

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

delims=

与用于处理具有隐藏属性集的文件的上述批处理文件相比,该单命令行版本旨在用于批处理文件,仅处理目录I中的所有非隐藏文件。

在这种情况下,

FOR 自己搜索目录@for %%I in ("C:\job\Folder\*") do @"%ProgramFiles%\7-Zip\7z.exe" a -p247bridges -y -- "C:\job\%%~nI" "%%I" 中的非隐藏文件,并将完整的合格文件名(文件路径+文件名+文件扩展名)分配给循环变量{ {1}},然后运行 7-Zip 将此文件压缩为存档文件,并将其压缩到目录C:\job\Folder中,存档文件名与压缩文件的名称相同。

添加了C:\job\Folder开关,以防止 7-Zip 发出任何提示,例如在存档文件上创建提示,以在目标目录中创建该文件。

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

在Windows x64上打开一个x64命令提示符窗口,然后运行以下两个命令以更好地理解 FOR 根据通配符模式集分配给指定循环变量C:\job\Folder的内容:< / p>

*

输出是Windows目录,其中C:\job\Folder\*引用了所有带有文件扩展名I的所有非隐藏可执行文件的文件名cd /D %SystemRoot% for %I in (*.exe System32\cm*.exe %SystemRoot%\SysWOW64\cm*.exe) do @echo %I

  • 在Windows目录中找不到路径,该路径是与模式C:\Windows
  • 匹配的当前目录
  • 文件名以%SytemRoot%开头,并在系统目录中找到x64应用程序的相对路径.exe,并由模式*
  • 匹配
  • 在系统目录中找到与模式cm匹配的x86应用程序的文件名以System32\开头的绝对路径为System32\cm*.exe

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

好吧,在第一个批处理文件中,将cm(属性NOT目录)替换为C:\Windows\SysWOW64\(属性目录),以处理C:\Windows\SysWOW64\cm*.exe中的所有子目录,包括隐藏的子目录,并追加{{1} }到 7-Zip 的最后一个参数,或使用开关/A-D进行递归压缩,或者甚至两者都使用。

/AD

然后在单命令行解决方案中,在C:\job\Folder\之间插入选项-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 中所有子目录(隐藏子目录除外)并修改像上面的7-Zip 参数列表。

/D

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

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

要获取有关通过命令行使用 7-Zip 的帮助,请在 7-Zip 的程序文件目录中双击其* .chm文件,或启动< strong> 7-Zip 并打开帮助(相同的帮助文件),选择第一个选项卡内容,双击列表项 Command Line Version 并阅读引用的内容帮助页面。