我有两组文件夹:
“ C:\ temp \ eFS_manual_temp”包含一组子文件夹。另一个目录“ C:\ temp \ eFS_manual \ eFS”包含相同的子文件夹集。
我想使用以下批处理脚本将子文件夹中的所有文件一次压缩为一个文件夹,然后将zip文件移动到具有相同文件夹结构的辅助位置:
SET SourceDir=C:\temp\eFS_manual\_temp
SET DestDir=C:\temp\eFS_manual\eFS
for /D %%a in ("%SourceDir%") do (
CD /D "C:\Program Files\WinRAR"
FOR /F "TOKENS=*" %%F IN ('DIR /B /A-D "%SourceDir%\%%a"') DO (
RAR.exe a -ep "%DestDir%\%%a\%%~NF.zip" "%SourceDir%\%%a\%%~NXF"
)
)
我收到以下错误消息:文件名,目录名或卷标签语法不正确。
答案 0 :(得分:0)
对我而言,最棘手的部分是将新的目录路径内置到$NewDir
中。完成此操作后,使用Compress-Archive
制作.zip格式的存档非常容易。假设您要在源目录不包含任何文件的情况下创建空目录。
由于您需要一个.zip存档文件,因此我使用了Compress-Archive
。如果您要使用其他工具(rar.exe或7z.exe),可以对其进行一些更改来代替它。
$SourceDir = 'C:\src\t'
$DestDir = 'C:\src\tarch'
Get-ChildItem -Recurse -Directory -Path $SourceDir |
ForEach-Object {
$SubName = $_.FullName.Replace($SourceDir, '')
$NewDir = $DestDir + $SubName
if (-not (Test-Path -Path $NewDir)) { New-Item -ItemType Directory -Path $NewDir }
$files = Get-ChildItem -File -Path $_.FullName
if ($files.Count -gt 0) {
$files | Compress-Archive -DestinationPath $NewDir\archcopy.zip
}
}
要在.bat文件脚本中运行此命令,请将上面的代码放入Archive-eFS_manual.ps1
之类的文件中。使用以下命令运行它:
powershell -NoProfile -File .\Archive-eFS_manual.ps1
答案 1 :(得分:0)
批处理文件代码的几行包含几个错误。
第一个在线for /D %%a in ("%SourceDir%") do
上。 FOR 在不包含任何通配符的圆括号中对选项/D
进行了忽略。打开命令提示符窗口并运行,很容易看到这一点:
for /D %I in ("%SystemRoot%") do @echo %I
此命令行仅打印"C:\Windows"
,它恰好是括号中的字符串。
因此,让我们运行此命令行并附加一个通配符:
for /D %I in ("%SystemRoot%\*") do @echo %I
输出要好得多,因为Windows系统目录中列出了所有非隐藏的子目录。
这是批处理文件执行时出现错误消息的主要错误结果,并与以下所述的其他错误结合。
命令行中存在多个错误
FOR /F "TOKENS=*" %%F IN ('DIR /B /A-D "%SourceDir%\%%a"') DO
%%a
将扩展为外部 FOR 命令行中%SourceDir%
中子目录的完全限定名称。 FOR 仅将指定的循环变量分配给位于圆括号中的未隐藏目录的名称,该名称不包含路径,即仅for /D %I in (*) do @echo %I
将用于处理当前目录中的未隐藏子目录。但是在包含绝对或相对路径的括号中进行设置时, FOR 会将具有指定绝对或相对路径的目录名称分配给指定的循环变量。在以下命令的命令提示符窗口中运行时,可以看到此行为:
cd /D %SystemDrive%\
for /D %I in (.\*) do @echo %I
for /D %I in (%SystemDrive%\*) do @echo %I
RAR.exe
会自动提取存档,将整个目录树创建到指定的目标目录。但是目标目录必须在创建归档文件时已存在。因此,建议在目标目录中确保源目录中的当前子目录也存在于目标目录中。
FOR 在以cmd.exe /C
为背景的单独命令过程中执行嵌入式 DIR 命令行,并捕获所有输出以处理 STDOUT < / strong>,由 DIR 完成。 DIR 在这种情况下仅输出所有文件的文件扩展名,包括在指定目录中找到具有隐藏属性集的文件。
捕获的空行被 FOR 跳过,由于默认为;
,因此以eol=;
开头的行将被跳过。 tokens=*
会导致从捕获的行中删除前导空格/制表符,如果还有剩余的内容,则剩余的行将分配给指定的循环变量,以供正文中的命令处理> FOR 循环。如果文件名以空格或分号开头,则该行为不好。最好使用delims=
来完全关闭行拆分行为,并为指定的循环变量分配完整的文件名。
但是即使修复了所有这些错误,仍然会有问题。控制台应用程序Rar.exe
的手册是 WinRAR 程序文件文件夹中的文本文件Rar.txt
。它清楚地说明了Rar.exe
仅支持 RAR 存档。它不支持其他存档类型,例如WinRAR.exe
支持的 ZIP 。因此Rar.exe
不能用于创建ZIP存档文件。
示例使开发人员的生活更加轻松,因此让我们从示例开始:
源目录C:\temp\eFS_manual\_temp
包含以下目录和文件:
由于批处理文件的处理,这真是丑陋的文件名,因为
文件和目录都没有设置隐藏属性。
批处理文件执行后,目标目录C:\temp\eFS_manual\eFS
仍应包含:
ZIP文件当然是真正的ZIP压缩存档文件,每个压缩文件只包含一个没有路径的压缩文件。
此目标可以通过以下方式实现:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SourceDir=C:\temp\eFS_manual\_temp"
set "DestDir=C:\temp\eFS_manual\eFS"
for /D %%I in ("%SourceDir%\*") do (
md "%DestDir%\%%~nxI" 2>nul
for %%J in ("%%I\*") do (
if not "%%~nJ" == "" (
"%ProgramFiles%\WinRAR\WinRAR.exe" a -afzip -cfg- -ep -ibck -inul -m5 -y -- "%DestDir%\%%~nxI\%%~nJ.zip" "%%J"
) else (
"%ProgramFiles%\WinRAR\WinRAR.exe" a -afzip -cfg- -ep -ibck -inul -m5 -y -- "%DestDir%\%%~nxI\%%~xJ.zip" "%%J"
)
)
)
endlocal
通过将第一行更改为@echo on
并从命令提示符窗口中运行该批处理文件可以看出该批处理文件的工作方式,在这种情况下,Windows命令处理器会按照上述说明在预处理/解析后输出每一行在执行命令行之前,在How does the Windows Command Interpreter (CMD.EXE) parse scripts?处。
如果源目录中还存在具有隐藏属性集的目录或文件,则必须使用命令 DIR 。
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SourceDir=C:\temp\eFS_manual\_temp"
set "DestDir=C:\temp\eFS_manual\eFS"
for /F "eol=| delims=" %%I in ('dir "%SourceDir%\*" /AD /B 2^>nul') do (
md "%DestDir%\%%I" 2>nul
for /F "eol=| delims=" %%J in ('dir "%SourceDir%\%%I\*" /A-D /B 2^>nul') do (
if not "%%~nJ" == "" (
"%ProgramFiles%\WinRAR\WinRAR.exe" a -afzip -cfg- -ep -ibck -inul -m5 -y -- "%DestDir%\%%I\%%~nJ.zip" "%SourceDir%\%%I\%%J"
) else (
"%ProgramFiles%\WinRAR\WinRAR.exe" a -afzip -cfg- -ep -ibck -inul -m5 -y -- "%DestDir%\%%I\%%~xJ.zip" "%SourceDir%\%%I\%%J"
)
)
)
endlocal
此批处理文件考虑到 DIR (带有选项/B
,不带选项/S
)始终输出目录和文件名而没有路径。
请阅读有关Using Command Redirection Operators的Microsoft文章,以获取2>nul
的解释。当Windows命令解释器在执行命令之前处理此命令行时,重定向操作符>
必须在 FOR 命令行上使用脱字符号^
进行转义,才能被解释为文字字符。 FOR ,它将在后台启动的单独命令进程中执行嵌入式dir
命令行。
WinRAR 命令行由
创建a
作为要使用的命令为此任务,要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面。
dir /?
echo /?
endlocal /?
for /?
if /?
md /?
set /?
setlocal /?